diff options
author | hyokeun <hyokeun.jeon@samsung.com> | 2016-12-27 17:29:09 +0900 |
---|---|---|
committer | hyokeun <hyokeun.jeon@samsung.com> | 2016-12-27 17:29:09 +0900 |
commit | 2a84d37c88d606fda46a565bcc80e173b4d0a80a (patch) | |
tree | 8b755bb78271e76e13fb7db38b670dbc443479e7 /target-s390x | |
parent | bd54c25035217800f3b1d39f6472d599cd602d5a (diff) | |
download | qemu-2a84d37c88d606fda46a565bcc80e173b4d0a80a.tar.gz qemu-2a84d37c88d606fda46a565bcc80e173b4d0a80a.tar.bz2 qemu-2a84d37c88d606fda46a565bcc80e173b4d0a80a.zip |
Imported Upstream version 2.6.1upstream/2.6.1upstream
Diffstat (limited to 'target-s390x')
-rw-r--r-- | target-s390x/cc_helper.c | 1 | ||||
-rw-r--r-- | target-s390x/cpu-qom.h | 46 | ||||
-rw-r--r-- | target-s390x/cpu.c | 4 | ||||
-rw-r--r-- | target-s390x/cpu.h | 195 | ||||
-rw-r--r-- | target-s390x/fpu_helper.c | 29 | ||||
-rw-r--r-- | target-s390x/gdbstub.c | 2 | ||||
-rw-r--r-- | target-s390x/helper.c | 10 | ||||
-rw-r--r-- | target-s390x/helper.h | 6 | ||||
-rw-r--r-- | target-s390x/int_helper.c | 1 | ||||
-rw-r--r-- | target-s390x/interrupt.c | 66 | ||||
-rw-r--r-- | target-s390x/ioinst.c | 3 | ||||
-rw-r--r-- | target-s390x/ioinst.h | 246 | ||||
-rw-r--r-- | target-s390x/kvm.c | 44 | ||||
-rw-r--r-- | target-s390x/machine.c | 32 | ||||
-rw-r--r-- | target-s390x/mem_helper.c | 10 | ||||
-rw-r--r-- | target-s390x/misc_helper.c | 23 | ||||
-rw-r--r-- | target-s390x/trace-events | 22 | ||||
-rw-r--r-- | target-s390x/translate.c | 28 |
18 files changed, 456 insertions, 312 deletions
diff --git a/target-s390x/cc_helper.c b/target-s390x/cc_helper.c index 1cf855133..0d9411bdf 100644 --- a/target-s390x/cc_helper.c +++ b/target-s390x/cc_helper.c @@ -20,7 +20,6 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "exec/exec-all.h" #include "exec/helper-proto.h" #include "qemu/host-utils.h" diff --git a/target-s390x/cpu-qom.h b/target-s390x/cpu-qom.h index 66b5d1808..1c9093396 100644 --- a/target-s390x/cpu-qom.h +++ b/target-s390x/cpu-qom.h @@ -21,6 +21,7 @@ #define QEMU_S390_CPU_QOM_H #include "qom/cpu.h" +#include "cpu.h" #define TYPE_S390_CPU "s390-cpu" @@ -55,6 +56,49 @@ typedef struct S390CPUClass { void (*initial_cpu_reset)(CPUState *cpu); } S390CPUClass; -typedef struct S390CPU S390CPU; +/** + * S390CPU: + * @env: #CPUS390XState. + * + * An S/390 CPU. + */ +typedef struct S390CPU { + /*< private >*/ + CPUState parent_obj; + /*< public >*/ + + CPUS390XState env; + int64_t id; + /* needed for live migration */ + void *irqstate; + uint32_t irqstate_saved_size; +} S390CPU; + +static inline S390CPU *s390_env_get_cpu(CPUS390XState *env) +{ + return container_of(env, S390CPU, env); +} + +#define ENV_GET_CPU(e) CPU(s390_env_get_cpu(e)) + +#define ENV_OFFSET offsetof(S390CPU, env) + +#ifndef CONFIG_USER_ONLY +extern const struct VMStateDescription vmstate_s390_cpu; +#endif + +void s390_cpu_do_interrupt(CPUState *cpu); +bool s390_cpu_exec_interrupt(CPUState *cpu, int int_req); +void s390_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, + int flags); +int s390_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs, + int cpuid, void *opaque); + +hwaddr s390_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); +hwaddr s390_cpu_get_phys_addr_debug(CPUState *cpu, vaddr addr); +int s390_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg); +int s390_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); +void s390_cpu_gdb_init(CPUState *cs); +void s390x_cpu_debug_excp_handler(CPUState *cs); #endif diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c index e43e2d615..4bfff341d 100644 --- a/target-s390x/cpu.c +++ b/target-s390x/cpu.c @@ -30,12 +30,10 @@ #include "qemu/cutils.h" #include "qemu/timer.h" #include "qemu/error-report.h" +#include "hw/hw.h" #include "trace.h" #include "qapi/visitor.h" -#include "migration/vmstate.h" -#include "exec/exec-all.h" #ifndef CONFIG_USER_ONLY -#include "hw/hw.h" #include "sysemu/arch_init.h" #include "sysemu/sysemu.h" #include "hw/s390x/sclp.h" diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h index c216bdace..6d97c089a 100644 --- a/target-s390x/cpu.h +++ b/target-s390x/cpu.h @@ -19,12 +19,10 @@ * You should have received a copy of the GNU (Lesser) General Public * License along with this library; if not, see <http://www.gnu.org/licenses/>. */ - -#ifndef S390X_CPU_H -#define S390X_CPU_H +#ifndef CPU_S390X_H +#define CPU_S390X_H #include "qemu-common.h" -#include "cpu-qom.h" #define TARGET_LONG_BITS 64 @@ -137,8 +135,6 @@ typedef struct CPUS390XState { uint64_t gbea; uint64_t pp; - uint8_t riccb[64]; - CPU_COMMON /* reset does memset(0) up to here */ @@ -175,52 +171,8 @@ static inline CPU_DoubleU *get_freg(CPUS390XState *cs, int nr) return &cs->vregs[nr][0]; } -/** - * S390CPU: - * @env: #CPUS390XState. - * - * An S/390 CPU. - */ -struct S390CPU { - /*< private >*/ - CPUState parent_obj; - /*< public >*/ - - CPUS390XState env; - int64_t id; - /* needed for live migration */ - void *irqstate; - uint32_t irqstate_saved_size; -}; - -static inline S390CPU *s390_env_get_cpu(CPUS390XState *env) -{ - return container_of(env, S390CPU, env); -} - -#define ENV_GET_CPU(e) CPU(s390_env_get_cpu(e)) - -#define ENV_OFFSET offsetof(S390CPU, env) - -#ifndef CONFIG_USER_ONLY -extern const struct VMStateDescription vmstate_s390_cpu; -#endif - -void s390_cpu_do_interrupt(CPUState *cpu); -bool s390_cpu_exec_interrupt(CPUState *cpu, int int_req); -void s390_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, - int flags); -int s390_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs, - int cpuid, void *opaque); - -hwaddr s390_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); -hwaddr s390_cpu_get_phys_addr_debug(CPUState *cpu, vaddr addr); -int s390_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg); -int s390_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); -void s390_cpu_gdb_init(CPUState *cs); -void s390x_cpu_debug_excp_handler(CPUState *cs); - -#include "sysemu/kvm.h" +#include "cpu-qom.h" +#include <sysemu/kvm.h> /* distinguish between 24 bit and 31 bit addressing */ #define HIGH_ORDER_BIT 0x80000000 @@ -386,7 +338,7 @@ static inline uint64_t cpu_mmu_idx_to_asc(int mmu_idx) } static inline void cpu_get_tb_cpu_state(CPUS390XState* env, target_ulong *pc, - target_ulong *cs_base, uint32_t *flags) + target_ulong *cs_base, int *flags) { *pc = env->psw.addr; *cs_base = 0; @@ -464,6 +416,7 @@ S390CPU *cpu_s390x_init(const char *cpu_model); S390CPU *s390x_new_cpu(const char *cpu_model, int64_t id, Error **errp); S390CPU *cpu_s390x_create(const char *cpu_model, Error **errp); void s390x_translate_init(void); +int cpu_s390x_exec(CPUState *cpu); /* you can call this signal handler from your SIGBUS and SIGSEGV signal handlers to inform the virtual CPU of exceptions. non zero @@ -473,6 +426,8 @@ int cpu_s390x_signal_handler(int host_signum, void *pinfo, int s390_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw, int mmu_idx); +#include "ioinst.h" + #ifndef CONFIG_USER_ONLY void do_restart_interrupt(CPUS390XState *env); @@ -583,26 +538,6 @@ static inline uint8_t s390_cpu_get_state(S390CPU *cpu) void gtod_save(QEMUFile *f, void *opaque); int gtod_load(QEMUFile *f, void *opaque, int version_id); -void cpu_inject_ext(S390CPU *cpu, uint32_t code, uint32_t param, - uint64_t param64); - -/* ioinst.c */ -void ioinst_handle_xsch(S390CPU *cpu, uint64_t reg1); -void ioinst_handle_csch(S390CPU *cpu, uint64_t reg1); -void ioinst_handle_hsch(S390CPU *cpu, uint64_t reg1); -void ioinst_handle_msch(S390CPU *cpu, uint64_t reg1, uint32_t ipb); -void ioinst_handle_ssch(S390CPU *cpu, uint64_t reg1, uint32_t ipb); -void ioinst_handle_stcrw(S390CPU *cpu, uint32_t ipb); -void ioinst_handle_stsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb); -int ioinst_handle_tsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb); -void ioinst_handle_chsc(S390CPU *cpu, uint32_t ipb); -int ioinst_handle_tpi(S390CPU *cpu, uint32_t ipb); -void ioinst_handle_schm(S390CPU *cpu, uint64_t reg1, uint64_t reg2, - uint32_t ipb); -void ioinst_handle_rsch(S390CPU *cpu, uint64_t reg1); -void ioinst_handle_rchp(S390CPU *cpu, uint64_t reg1); -void ioinst_handle_sal(S390CPU *cpu, uint64_t reg1); - /* service interrupts are floating therefore we must not pass an cpustate */ void s390_sclp_extint(uint32_t parm); @@ -624,14 +559,45 @@ static inline unsigned int s390_cpu_set_state(uint8_t cpu_state, S390CPU *cpu) void cpu_lock(void); void cpu_unlock(void); +typedef struct SubchDev SubchDev; + +#ifndef CONFIG_USER_ONLY extern void subsystem_reset(void); +SubchDev *css_find_subch(uint8_t m, uint8_t cssid, uint8_t ssid, + uint16_t schid); +bool css_subch_visible(SubchDev *sch); +void css_conditional_io_interrupt(SubchDev *sch); +int css_do_stsch(SubchDev *sch, SCHIB *schib); +bool css_schid_final(int m, uint8_t cssid, uint8_t ssid, uint16_t schid); +int css_do_msch(SubchDev *sch, const SCHIB *schib); +int css_do_xsch(SubchDev *sch); +int css_do_csch(SubchDev *sch); +int css_do_hsch(SubchDev *sch); +int css_do_ssch(SubchDev *sch, ORB *orb); +int css_do_tsch_get_irb(SubchDev *sch, IRB *irb, int *irb_len); +void css_do_tsch_update_subch(SubchDev *sch); +int css_do_stcrw(CRW *crw); +void css_undo_stcrw(CRW *crw); +int css_do_tpi(IOIntCode *int_code, int lowcore); +int css_collect_chp_desc(int m, uint8_t cssid, uint8_t f_chpid, uint8_t l_chpid, + int rfmt, void *buf); +void css_do_schm(uint8_t mbk, int update, int dct, uint64_t mbo); +int css_enable_mcsse(void); +int css_enable_mss(void); +int css_do_rsch(SubchDev *sch); +int css_do_rchp(uint8_t cssid, uint8_t chpid); +bool css_present(uint8_t cssid); +#endif #define cpu_init(model) CPU(cpu_s390x_init(model)) +#define cpu_exec cpu_s390x_exec #define cpu_signal_handler cpu_s390x_signal_handler void s390_cpu_list(FILE *f, fprintf_function cpu_fprintf); #define cpu_list s390_cpu_list +#include "exec/exec-all.h" + #define EXCP_EXT 1 /* external interrupt */ #define EXCP_SVC 2 /* supervisor call (syscall) */ #define EXCP_PGM 3 /* program interruption */ @@ -1096,6 +1062,69 @@ static inline uint64_t tod2time(uint64_t t) { return (t * 125) >> 9; } +static inline void cpu_inject_ext(S390CPU *cpu, uint32_t code, uint32_t param, + uint64_t param64) +{ + CPUS390XState *env = &cpu->env; + + if (env->ext_index == MAX_EXT_QUEUE - 1) { + /* ugh - can't queue anymore. Let's drop. */ + return; + } + + env->ext_index++; + assert(env->ext_index < MAX_EXT_QUEUE); + + env->ext_queue[env->ext_index].code = code; + env->ext_queue[env->ext_index].param = param; + env->ext_queue[env->ext_index].param64 = param64; + + env->pending_int |= INTERRUPT_EXT; + cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HARD); +} + +static inline void cpu_inject_io(S390CPU *cpu, uint16_t subchannel_id, + uint16_t subchannel_number, + uint32_t io_int_parm, uint32_t io_int_word) +{ + CPUS390XState *env = &cpu->env; + int isc = IO_INT_WORD_ISC(io_int_word); + + if (env->io_index[isc] == MAX_IO_QUEUE - 1) { + /* ugh - can't queue anymore. Let's drop. */ + return; + } + + env->io_index[isc]++; + assert(env->io_index[isc] < MAX_IO_QUEUE); + + env->io_queue[env->io_index[isc]][isc].id = subchannel_id; + env->io_queue[env->io_index[isc]][isc].nr = subchannel_number; + env->io_queue[env->io_index[isc]][isc].parm = io_int_parm; + env->io_queue[env->io_index[isc]][isc].word = io_int_word; + + env->pending_int |= INTERRUPT_IO; + cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HARD); +} + +static inline void cpu_inject_crw_mchk(S390CPU *cpu) +{ + CPUS390XState *env = &cpu->env; + + if (env->mchk_index == MAX_MCHK_QUEUE - 1) { + /* ugh - can't queue anymore. Let's drop. */ + return; + } + + env->mchk_index++; + assert(env->mchk_index < MAX_MCHK_QUEUE); + + env->mchk_queue[env->mchk_index].type = 1; + + env->pending_int |= INTERRUPT_MCHK; + cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HARD); +} + /* from s390-virtio-ccw */ #define MEM_SECTION_SIZE 0x10000000UL #define MAX_AVAIL_SLOTS 32 @@ -1130,7 +1159,6 @@ void kvm_s390_reset_vcpu(S390CPU *cpu); int kvm_s390_set_mem_limit(KVMState *s, uint64_t new_limit, uint64_t *hw_limit); void kvm_s390_vcpu_interrupt_pre_save(S390CPU *cpu); int kvm_s390_vcpu_interrupt_post_load(S390CPU *cpu); -int kvm_s390_get_ri(void); void kvm_s390_crypto_reset(void); #else static inline void kvm_s390_io_interrupt(uint16_t subchannel_id, @@ -1181,10 +1209,6 @@ static inline int kvm_s390_vcpu_interrupt_post_load(S390CPU *cpu) { return 0; } -static inline int kvm_s390_get_ri(void) -{ - return 0; -} static inline void kvm_s390_crypto_reset(void) { } @@ -1240,6 +1264,21 @@ static inline void s390_crypto_reset(void) } } +#ifdef CONFIG_KVM +static inline bool vregs_needed(void *opaque) +{ + if (kvm_enabled()) { + return kvm_check_extension(kvm_state, KVM_CAP_S390_VECTOR_REGISTERS); + } + return 0; +} +#else +static inline bool vregs_needed(void *opaque) +{ + return 0; +} +#endif + /* machine check interruption code */ /* subclasses */ diff --git a/target-s390x/fpu_helper.c b/target-s390x/fpu_helper.c index e604e9f7b..1c7f67354 100644 --- a/target-s390x/fpu_helper.c +++ b/target-s390x/fpu_helper.c @@ -20,7 +20,6 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "exec/exec-all.h" #include "exec/cpu_ldst.h" #include "exec/helper-proto.h" @@ -267,7 +266,7 @@ uint64_t HELPER(ldeb)(CPUS390XState *env, uint64_t f2) { float64 ret = float32_to_float64(f2, &env->fpu_status); handle_exceptions(env, GETPC()); - return float64_maybe_silence_nan(ret, &env->fpu_status); + return float64_maybe_silence_nan(ret); } /* convert 128-bit float to 64-bit float */ @@ -275,7 +274,7 @@ uint64_t HELPER(ldxb)(CPUS390XState *env, uint64_t ah, uint64_t al) { float64 ret = float128_to_float64(make_float128(ah, al), &env->fpu_status); handle_exceptions(env, GETPC()); - return float64_maybe_silence_nan(ret, &env->fpu_status); + return float64_maybe_silence_nan(ret); } /* convert 64-bit float to 128-bit float */ @@ -283,7 +282,7 @@ uint64_t HELPER(lxdb)(CPUS390XState *env, uint64_t f2) { float128 ret = float64_to_float128(f2, &env->fpu_status); handle_exceptions(env, GETPC()); - return RET128(float128_maybe_silence_nan(ret, &env->fpu_status)); + return RET128(float128_maybe_silence_nan(ret)); } /* convert 32-bit float to 128-bit float */ @@ -291,7 +290,7 @@ uint64_t HELPER(lxeb)(CPUS390XState *env, uint64_t f2) { float128 ret = float32_to_float128(f2, &env->fpu_status); handle_exceptions(env, GETPC()); - return RET128(float128_maybe_silence_nan(ret, &env->fpu_status)); + return RET128(float128_maybe_silence_nan(ret)); } /* convert 64-bit float to 32-bit float */ @@ -299,7 +298,7 @@ uint64_t HELPER(ledb)(CPUS390XState *env, uint64_t f2) { float32 ret = float64_to_float32(f2, &env->fpu_status); handle_exceptions(env, GETPC()); - return float32_maybe_silence_nan(ret, &env->fpu_status); + return float32_maybe_silence_nan(ret); } /* convert 128-bit float to 32-bit float */ @@ -307,7 +306,7 @@ uint64_t HELPER(lexb)(CPUS390XState *env, uint64_t ah, uint64_t al) { float32 ret = float128_to_float32(make_float128(ah, al), &env->fpu_status); handle_exceptions(env, GETPC()); - return float32_maybe_silence_nan(ret, &env->fpu_status); + return float32_maybe_silence_nan(ret); } /* 32-bit FP compare */ @@ -624,7 +623,7 @@ uint64_t HELPER(msdb)(CPUS390XState *env, uint64_t f1, } /* test data class 32-bit */ -uint32_t HELPER(tceb)(CPUS390XState *env, uint64_t f1, uint64_t m2) +uint32_t HELPER(tceb)(uint64_t f1, uint64_t m2) { float32 v1 = f1; int neg = float32_is_neg(v1); @@ -633,8 +632,7 @@ uint32_t HELPER(tceb)(CPUS390XState *env, uint64_t f1, uint64_t m2) if ((float32_is_zero(v1) && (m2 & (1 << (11-neg)))) || (float32_is_infinity(v1) && (m2 & (1 << (5-neg)))) || (float32_is_any_nan(v1) && (m2 & (1 << (3-neg)))) || - (float32_is_signaling_nan(v1, &env->fpu_status) && - (m2 & (1 << (1-neg))))) { + (float32_is_signaling_nan(v1) && (m2 & (1 << (1-neg))))) { cc = 1; } else if (m2 & (1 << (9-neg))) { /* assume normalized number */ @@ -645,7 +643,7 @@ uint32_t HELPER(tceb)(CPUS390XState *env, uint64_t f1, uint64_t m2) } /* test data class 64-bit */ -uint32_t HELPER(tcdb)(CPUS390XState *env, uint64_t v1, uint64_t m2) +uint32_t HELPER(tcdb)(uint64_t v1, uint64_t m2) { int neg = float64_is_neg(v1); uint32_t cc = 0; @@ -653,8 +651,7 @@ uint32_t HELPER(tcdb)(CPUS390XState *env, uint64_t v1, uint64_t m2) if ((float64_is_zero(v1) && (m2 & (1 << (11-neg)))) || (float64_is_infinity(v1) && (m2 & (1 << (5-neg)))) || (float64_is_any_nan(v1) && (m2 & (1 << (3-neg)))) || - (float64_is_signaling_nan(v1, &env->fpu_status) && - (m2 & (1 << (1-neg))))) { + (float64_is_signaling_nan(v1) && (m2 & (1 << (1-neg))))) { cc = 1; } else if (m2 & (1 << (9-neg))) { /* assume normalized number */ @@ -665,8 +662,7 @@ uint32_t HELPER(tcdb)(CPUS390XState *env, uint64_t v1, uint64_t m2) } /* test data class 128-bit */ -uint32_t HELPER(tcxb)(CPUS390XState *env, uint64_t ah, - uint64_t al, uint64_t m2) +uint32_t HELPER(tcxb)(uint64_t ah, uint64_t al, uint64_t m2) { float128 v1 = make_float128(ah, al); int neg = float128_is_neg(v1); @@ -675,8 +671,7 @@ uint32_t HELPER(tcxb)(CPUS390XState *env, uint64_t ah, if ((float128_is_zero(v1) && (m2 & (1 << (11-neg)))) || (float128_is_infinity(v1) && (m2 & (1 << (5-neg)))) || (float128_is_any_nan(v1) && (m2 & (1 << (3-neg)))) || - (float128_is_signaling_nan(v1, &env->fpu_status) && - (m2 & (1 << (1-neg))))) { + (float128_is_signaling_nan(v1) && (m2 & (1 << (1-neg))))) { cc = 1; } else if (m2 & (1 << (9-neg))) { /* assume normalized number */ diff --git a/target-s390x/gdbstub.c b/target-s390x/gdbstub.c index 3d223dec9..9fc36cb54 100644 --- a/target-s390x/gdbstub.c +++ b/target-s390x/gdbstub.c @@ -19,8 +19,6 @@ */ #include "qemu/osdep.h" #include "qemu-common.h" -#include "cpu.h" -#include "exec/exec-all.h" #include "exec/gdbstub.h" #include "qemu/bitops.h" diff --git a/target-s390x/helper.c b/target-s390x/helper.c index 54a517734..92abe7e67 100644 --- a/target-s390x/helper.c +++ b/target-s390x/helper.c @@ -23,9 +23,7 @@ #include "cpu.h" #include "exec/gdbstub.h" #include "qemu/timer.h" -#include "exec/exec-all.h" #include "exec/cpu_ldst.h" -#include "hw/s390x/ioinst.h" #ifndef CONFIG_USER_ONLY #include "sysemu/sysemu.h" #endif @@ -70,7 +68,11 @@ void s390x_cpu_timer(void *opaque) S390CPU *cpu_s390x_create(const char *cpu_model, Error **errp) { - return S390_CPU(object_new(TYPE_S390_CPU)); + S390CPU *cpu; + + cpu = S390_CPU(object_new(TYPE_S390_CPU)); + + return cpu; } S390CPU *s390x_new_cpu(const char *cpu_model, int64_t id, Error **errp) @@ -684,7 +686,7 @@ void s390x_cpu_debug_excp_handler(CPUState *cs) will be triggered, it will call load_psw which will recompute the watchpoints. */ cpu_watchpoint_remove_all(cs, BP_CPU); - cpu_loop_exit_noexc(cs); + cpu_resume_from_signal(cs, NULL); } } #endif /* CONFIG_USER_ONLY */ diff --git a/target-s390x/helper.h b/target-s390x/helper.h index 207a6e7d1..7e06119e9 100644 --- a/target-s390x/helper.h +++ b/target-s390x/helper.h @@ -67,9 +67,9 @@ DEF_HELPER_FLAGS_4(maeb, TCG_CALL_NO_WG, i64, env, i64, i64, i64) DEF_HELPER_FLAGS_4(madb, TCG_CALL_NO_WG, i64, env, i64, i64, i64) DEF_HELPER_FLAGS_4(mseb, TCG_CALL_NO_WG, i64, env, i64, i64, i64) DEF_HELPER_FLAGS_4(msdb, TCG_CALL_NO_WG, i64, env, i64, i64, i64) -DEF_HELPER_FLAGS_3(tceb, TCG_CALL_NO_RWG_SE, i32, env, i64, i64) -DEF_HELPER_FLAGS_3(tcdb, TCG_CALL_NO_RWG_SE, i32, env, i64, i64) -DEF_HELPER_FLAGS_4(tcxb, TCG_CALL_NO_RWG_SE, i32, env, i64, i64, i64) +DEF_HELPER_FLAGS_2(tceb, TCG_CALL_NO_RWG_SE, i32, i64, i64) +DEF_HELPER_FLAGS_2(tcdb, TCG_CALL_NO_RWG_SE, i32, i64, i64) +DEF_HELPER_FLAGS_3(tcxb, TCG_CALL_NO_RWG_SE, i32, i64, i64, i64) DEF_HELPER_FLAGS_1(clz, TCG_CALL_NO_RWG_SE, i64, i64) DEF_HELPER_FLAGS_2(sqeb, TCG_CALL_NO_WG, i64, env, i64) DEF_HELPER_FLAGS_2(sqdb, TCG_CALL_NO_WG, i64, env, i64) diff --git a/target-s390x/int_helper.c b/target-s390x/int_helper.c index 370c94da5..cc1071eea 100644 --- a/target-s390x/int_helper.c +++ b/target-s390x/int_helper.c @@ -20,7 +20,6 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "exec/exec-all.h" #include "qemu/host-utils.h" #include "exec/helper-proto.h" diff --git a/target-s390x/interrupt.c b/target-s390x/interrupt.c index 9edef9679..bad60a7e1 100644 --- a/target-s390x/interrupt.c +++ b/target-s390x/interrupt.c @@ -10,77 +10,13 @@ #include "qemu/osdep.h" #include "cpu.h" #include "sysemu/kvm.h" -#include "hw/s390x/ioinst.h" - -#if !defined(CONFIG_USER_ONLY) -void cpu_inject_ext(S390CPU *cpu, uint32_t code, uint32_t param, - uint64_t param64) -{ - CPUS390XState *env = &cpu->env; - - if (env->ext_index == MAX_EXT_QUEUE - 1) { - /* ugh - can't queue anymore. Let's drop. */ - return; - } - - env->ext_index++; - assert(env->ext_index < MAX_EXT_QUEUE); - - env->ext_queue[env->ext_index].code = code; - env->ext_queue[env->ext_index].param = param; - env->ext_queue[env->ext_index].param64 = param64; - - env->pending_int |= INTERRUPT_EXT; - cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HARD); -} - -static void cpu_inject_io(S390CPU *cpu, uint16_t subchannel_id, - uint16_t subchannel_number, - uint32_t io_int_parm, uint32_t io_int_word) -{ - CPUS390XState *env = &cpu->env; - int isc = IO_INT_WORD_ISC(io_int_word); - - if (env->io_index[isc] == MAX_IO_QUEUE - 1) { - /* ugh - can't queue anymore. Let's drop. */ - return; - } - - env->io_index[isc]++; - assert(env->io_index[isc] < MAX_IO_QUEUE); - - env->io_queue[env->io_index[isc]][isc].id = subchannel_id; - env->io_queue[env->io_index[isc]][isc].nr = subchannel_number; - env->io_queue[env->io_index[isc]][isc].parm = io_int_parm; - env->io_queue[env->io_index[isc]][isc].word = io_int_word; - - env->pending_int |= INTERRUPT_IO; - cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HARD); -} - -static void cpu_inject_crw_mchk(S390CPU *cpu) -{ - CPUS390XState *env = &cpu->env; - - if (env->mchk_index == MAX_MCHK_QUEUE - 1) { - /* ugh - can't queue anymore. Let's drop. */ - return; - } - - env->mchk_index++; - assert(env->mchk_index < MAX_MCHK_QUEUE); - - env->mchk_queue[env->mchk_index].type = 1; - - env->pending_int |= INTERRUPT_MCHK; - cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HARD); -} /* * All of the following interrupts are floating, i.e. not per-vcpu. * We just need a dummy cpustate in order to be able to inject in the * non-kvm case. */ +#if !defined(CONFIG_USER_ONLY) void s390_sclp_extint(uint32_t parm) { if (kvm_enabled()) { diff --git a/target-s390x/ioinst.c b/target-s390x/ioinst.c index a5a288bec..142ff9384 100644 --- a/target-s390x/ioinst.c +++ b/target-s390x/ioinst.c @@ -12,7 +12,7 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "hw/s390x/ioinst.h" +#include "ioinst.h" #include "trace.h" #include "hw/s390x/s390-pci-bus.h" @@ -509,7 +509,6 @@ static void ioinst_handle_chsc_scsc(ChscReq *req, ChscResp *res) general_chars[0] = cpu_to_be32(0x03000000); general_chars[1] = cpu_to_be32(0x00059000); - general_chars[3] = cpu_to_be32(0x00080000); chsc_chars[0] = cpu_to_be32(0x40000000); chsc_chars[3] = cpu_to_be32(0x00040000); diff --git a/target-s390x/ioinst.h b/target-s390x/ioinst.h new file mode 100644 index 000000000..013cc9148 --- /dev/null +++ b/target-s390x/ioinst.h @@ -0,0 +1,246 @@ +/* + * S/390 channel I/O instructions + * + * Copyright 2012 IBM Corp. + * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com> + * + * This work is licensed under the terms of the GNU GPL, version 2 or (at + * your option) any later version. See the COPYING file in the top-level + * directory. +*/ + +#ifndef IOINST_S390X_H +#define IOINST_S390X_H +/* + * Channel I/O related definitions, as defined in the Principles + * Of Operation (and taken from the Linux implementation). + */ + +/* subchannel status word (command mode only) */ +typedef struct SCSW { + uint16_t flags; + uint16_t ctrl; + uint32_t cpa; + uint8_t dstat; + uint8_t cstat; + uint16_t count; +} QEMU_PACKED SCSW; + +#define SCSW_FLAGS_MASK_KEY 0xf000 +#define SCSW_FLAGS_MASK_SCTL 0x0800 +#define SCSW_FLAGS_MASK_ESWF 0x0400 +#define SCSW_FLAGS_MASK_CC 0x0300 +#define SCSW_FLAGS_MASK_FMT 0x0080 +#define SCSW_FLAGS_MASK_PFCH 0x0040 +#define SCSW_FLAGS_MASK_ISIC 0x0020 +#define SCSW_FLAGS_MASK_ALCC 0x0010 +#define SCSW_FLAGS_MASK_SSI 0x0008 +#define SCSW_FLAGS_MASK_ZCC 0x0004 +#define SCSW_FLAGS_MASK_ECTL 0x0002 +#define SCSW_FLAGS_MASK_PNO 0x0001 + +#define SCSW_CTRL_MASK_FCTL 0x7000 +#define SCSW_CTRL_MASK_ACTL 0x0fe0 +#define SCSW_CTRL_MASK_STCTL 0x001f + +#define SCSW_FCTL_CLEAR_FUNC 0x1000 +#define SCSW_FCTL_HALT_FUNC 0x2000 +#define SCSW_FCTL_START_FUNC 0x4000 + +#define SCSW_ACTL_SUSP 0x0020 +#define SCSW_ACTL_DEVICE_ACTIVE 0x0040 +#define SCSW_ACTL_SUBCH_ACTIVE 0x0080 +#define SCSW_ACTL_CLEAR_PEND 0x0100 +#define SCSW_ACTL_HALT_PEND 0x0200 +#define SCSW_ACTL_START_PEND 0x0400 +#define SCSW_ACTL_RESUME_PEND 0x0800 + +#define SCSW_STCTL_STATUS_PEND 0x0001 +#define SCSW_STCTL_SECONDARY 0x0002 +#define SCSW_STCTL_PRIMARY 0x0004 +#define SCSW_STCTL_INTERMEDIATE 0x0008 +#define SCSW_STCTL_ALERT 0x0010 + +#define SCSW_DSTAT_ATTENTION 0x80 +#define SCSW_DSTAT_STAT_MOD 0x40 +#define SCSW_DSTAT_CU_END 0x20 +#define SCSW_DSTAT_BUSY 0x10 +#define SCSW_DSTAT_CHANNEL_END 0x08 +#define SCSW_DSTAT_DEVICE_END 0x04 +#define SCSW_DSTAT_UNIT_CHECK 0x02 +#define SCSW_DSTAT_UNIT_EXCEP 0x01 + +#define SCSW_CSTAT_PCI 0x80 +#define SCSW_CSTAT_INCORR_LEN 0x40 +#define SCSW_CSTAT_PROG_CHECK 0x20 +#define SCSW_CSTAT_PROT_CHECK 0x10 +#define SCSW_CSTAT_DATA_CHECK 0x08 +#define SCSW_CSTAT_CHN_CTRL_CHK 0x04 +#define SCSW_CSTAT_INTF_CTRL_CHK 0x02 +#define SCSW_CSTAT_CHAIN_CHECK 0x01 + +/* path management control word */ +typedef struct PMCW { + uint32_t intparm; + uint16_t flags; + uint16_t devno; + uint8_t lpm; + uint8_t pnom; + uint8_t lpum; + uint8_t pim; + uint16_t mbi; + uint8_t pom; + uint8_t pam; + uint8_t chpid[8]; + uint32_t chars; +} QEMU_PACKED PMCW; + +#define PMCW_FLAGS_MASK_QF 0x8000 +#define PMCW_FLAGS_MASK_W 0x4000 +#define PMCW_FLAGS_MASK_ISC 0x3800 +#define PMCW_FLAGS_MASK_ENA 0x0080 +#define PMCW_FLAGS_MASK_LM 0x0060 +#define PMCW_FLAGS_MASK_MME 0x0018 +#define PMCW_FLAGS_MASK_MP 0x0004 +#define PMCW_FLAGS_MASK_TF 0x0002 +#define PMCW_FLAGS_MASK_DNV 0x0001 +#define PMCW_FLAGS_MASK_INVALID 0x0700 + +#define PMCW_CHARS_MASK_ST 0x00e00000 +#define PMCW_CHARS_MASK_MBFC 0x00000004 +#define PMCW_CHARS_MASK_XMWME 0x00000002 +#define PMCW_CHARS_MASK_CSENSE 0x00000001 +#define PMCW_CHARS_MASK_INVALID 0xff1ffff8 + +/* subchannel information block */ +typedef struct SCHIB { + PMCW pmcw; + SCSW scsw; + uint64_t mba; + uint8_t mda[4]; +} QEMU_PACKED SCHIB; + +/* interruption response block */ +typedef struct IRB { + SCSW scsw; + uint32_t esw[5]; + uint32_t ecw[8]; + uint32_t emw[8]; +} QEMU_PACKED IRB; + +/* operation request block */ +typedef struct ORB { + uint32_t intparm; + uint16_t ctrl0; + uint8_t lpm; + uint8_t ctrl1; + uint32_t cpa; +} QEMU_PACKED ORB; + +#define ORB_CTRL0_MASK_KEY 0xf000 +#define ORB_CTRL0_MASK_SPND 0x0800 +#define ORB_CTRL0_MASK_STR 0x0400 +#define ORB_CTRL0_MASK_MOD 0x0200 +#define ORB_CTRL0_MASK_SYNC 0x0100 +#define ORB_CTRL0_MASK_FMT 0x0080 +#define ORB_CTRL0_MASK_PFCH 0x0040 +#define ORB_CTRL0_MASK_ISIC 0x0020 +#define ORB_CTRL0_MASK_ALCC 0x0010 +#define ORB_CTRL0_MASK_SSIC 0x0008 +#define ORB_CTRL0_MASK_C64 0x0002 +#define ORB_CTRL0_MASK_I2K 0x0001 +#define ORB_CTRL0_MASK_INVALID 0x0004 + +#define ORB_CTRL1_MASK_ILS 0x80 +#define ORB_CTRL1_MASK_MIDAW 0x40 +#define ORB_CTRL1_MASK_ORBX 0x01 +#define ORB_CTRL1_MASK_INVALID 0x3e + +/* channel command word (type 0) */ +typedef struct CCW0 { + uint8_t cmd_code; + uint8_t cda0; + uint16_t cda1; + uint8_t flags; + uint8_t reserved; + uint16_t count; +} QEMU_PACKED CCW0; + +/* channel command word (type 1) */ +typedef struct CCW1 { + uint8_t cmd_code; + uint8_t flags; + uint16_t count; + uint32_t cda; +} QEMU_PACKED CCW1; + +#define CCW_FLAG_DC 0x80 +#define CCW_FLAG_CC 0x40 +#define CCW_FLAG_SLI 0x20 +#define CCW_FLAG_SKIP 0x10 +#define CCW_FLAG_PCI 0x08 +#define CCW_FLAG_IDA 0x04 +#define CCW_FLAG_SUSPEND 0x02 + +#define CCW_CMD_NOOP 0x03 +#define CCW_CMD_BASIC_SENSE 0x04 +#define CCW_CMD_TIC 0x08 +#define CCW_CMD_SENSE_ID 0xe4 + +typedef struct CRW { + uint16_t flags; + uint16_t rsid; +} QEMU_PACKED CRW; + +#define CRW_FLAGS_MASK_S 0x4000 +#define CRW_FLAGS_MASK_R 0x2000 +#define CRW_FLAGS_MASK_C 0x1000 +#define CRW_FLAGS_MASK_RSC 0x0f00 +#define CRW_FLAGS_MASK_A 0x0080 +#define CRW_FLAGS_MASK_ERC 0x003f + +#define CRW_ERC_INIT 0x02 +#define CRW_ERC_IPI 0x04 + +#define CRW_RSC_SUBCH 0x3 +#define CRW_RSC_CHP 0x4 +#define CRW_RSC_CSS 0xb + +/* I/O interruption code */ +typedef struct IOIntCode { + uint32_t subsys_id; + uint32_t intparm; + uint32_t interrupt_id; +} QEMU_PACKED IOIntCode; + +/* schid disintegration */ +#define IOINST_SCHID_ONE(_schid) ((_schid & 0x00010000) >> 16) +#define IOINST_SCHID_M(_schid) ((_schid & 0x00080000) >> 19) +#define IOINST_SCHID_CSSID(_schid) ((_schid & 0xff000000) >> 24) +#define IOINST_SCHID_SSID(_schid) ((_schid & 0x00060000) >> 17) +#define IOINST_SCHID_NR(_schid) (_schid & 0x0000ffff) + +#define IO_INT_WORD_ISC(_int_word) ((_int_word & 0x38000000) >> 27) +#define ISC_TO_ISC_BITS(_isc) ((0x80 >> _isc) << 24) + +#define IO_INT_WORD_AI 0x80000000 + +int ioinst_disassemble_sch_ident(uint32_t value, int *m, int *cssid, int *ssid, + int *schid); +void ioinst_handle_xsch(S390CPU *cpu, uint64_t reg1); +void ioinst_handle_csch(S390CPU *cpu, uint64_t reg1); +void ioinst_handle_hsch(S390CPU *cpu, uint64_t reg1); +void ioinst_handle_msch(S390CPU *cpu, uint64_t reg1, uint32_t ipb); +void ioinst_handle_ssch(S390CPU *cpu, uint64_t reg1, uint32_t ipb); +void ioinst_handle_stcrw(S390CPU *cpu, uint32_t ipb); +void ioinst_handle_stsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb); +int ioinst_handle_tsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb); +void ioinst_handle_chsc(S390CPU *cpu, uint32_t ipb); +int ioinst_handle_tpi(S390CPU *cpu, uint32_t ipb); +void ioinst_handle_schm(S390CPU *cpu, uint64_t reg1, uint64_t reg2, + uint32_t ipb); +void ioinst_handle_rsch(S390CPU *cpu, uint64_t reg1); +void ioinst_handle_rchp(S390CPU *cpu, uint64_t reg1); +void ioinst_handle_sal(S390CPU *cpu, uint64_t reg1); + +#endif diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c index 80ac6215f..e1859cae0 100644 --- a/target-s390x/kvm.c +++ b/target-s390x/kvm.c @@ -23,17 +23,18 @@ #include "qemu/osdep.h" #include <sys/ioctl.h> +#include <sys/mman.h> #include <linux/kvm.h> #include <asm/ptrace.h> #include "qemu-common.h" -#include "cpu.h" #include "qemu/error-report.h" #include "qemu/timer.h" #include "sysemu/sysemu.h" #include "sysemu/kvm.h" #include "hw/hw.h" +#include "cpu.h" #include "sysemu/device_tree.h" #include "qapi/qmp/qjson.h" #include "exec/gdbstub.h" @@ -45,7 +46,6 @@ #include "hw/s390x/ipl.h" #include "hw/s390x/ebcdic.h" #include "exec/memattrs.h" -#include "hw/s390x/s390-virtio-ccw.h" /* #define DEBUG_KVM */ @@ -135,7 +135,6 @@ static int cap_sync_regs; static int cap_async_pf; static int cap_mem_op; static int cap_s390_irq; -static int cap_ri; static void *legacy_s390_alloc(size_t size, uint64_t *align); @@ -271,11 +270,6 @@ int kvm_arch_init(MachineState *ms, KVMState *s) kvm_vm_enable_cap(s, KVM_CAP_S390_USER_SIGP, 0); kvm_vm_enable_cap(s, KVM_CAP_S390_VECTOR_REGISTERS, 0); kvm_vm_enable_cap(s, KVM_CAP_S390_USER_STSI, 0); - if (ri_allowed()) { - if (kvm_vm_enable_cap(s, KVM_CAP_S390_RI, 0) == 0) { - cap_ri = 1; - } - } return 0; } @@ -392,11 +386,6 @@ int kvm_arch_put_registers(CPUState *cs, int level) kvm_set_one_reg(cs, KVM_REG_S390_PP, &env->pp); } - if (can_sync_regs(cs, KVM_SYNC_RICCB)) { - memcpy(cs->kvm_run->s.regs.riccb, env->riccb, 64); - cs->kvm_run->kvm_dirty_regs |= KVM_SYNC_RICCB; - } - /* pfault parameters */ if (can_sync_regs(cs, KVM_SYNC_PFAULT)) { cs->kvm_run->s.regs.pft = env->pfault_token; @@ -539,10 +528,6 @@ int kvm_arch_get_registers(CPUState *cs) kvm_get_one_reg(cs, KVM_REG_S390_PP, &env->pp); } - if (can_sync_regs(cs, KVM_SYNC_RICCB)) { - memcpy(env->riccb, cs->kvm_run->s.regs.riccb, 64); - } - /* pfault parameters */ if (can_sync_regs(cs, KVM_SYNC_PFAULT)) { env->pfault_token = cs->kvm_run->s.regs.pft; @@ -2070,9 +2055,8 @@ void kvm_s390_io_interrupt(uint16_t subchannel_id, if (io_int_word & IO_INT_WORD_AI) { irq.type = KVM_S390_INT_IO(1, 0, 0, 0); } else { - irq.type = KVM_S390_INT_IO(0, (subchannel_id & 0xff00) >> 8, - (subchannel_id & 0x0006), - subchannel_nr); + irq.type = ((subchannel_id & 0xff00) << 24) | + ((subchannel_id & 0x00060) << 22) | (subchannel_nr << 16); } kvm_s390_floating_interrupt(&irq); } @@ -2152,11 +2136,6 @@ int kvm_s390_get_memslot_count(KVMState *s) return kvm_check_extension(s, KVM_CAP_NR_MEMSLOTS); } -int kvm_s390_get_ri(void) -{ - return cap_ri; -} - int kvm_s390_set_cpu_state(S390CPU *cpu, uint8_t cpu_state) { struct kvm_mp_state mp_state = {}; @@ -2246,10 +2225,10 @@ int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route, uint64_t address, uint32_t data, PCIDevice *dev) { S390PCIBusDevice *pbdev; - uint32_t idx = data >> ZPCI_MSI_VEC_BITS; + uint32_t fid = data >> ZPCI_MSI_VEC_BITS; uint32_t vec = data & ZPCI_MSI_VEC_MASK; - pbdev = s390_pci_find_dev_by_idx(idx); + pbdev = s390_pci_find_dev_by_fid(fid); if (!pbdev) { DPRINTF("add_msi_route no dev\n"); return -ENODEV; @@ -2267,17 +2246,6 @@ int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route, return 0; } -int kvm_arch_add_msi_route_post(struct kvm_irq_routing_entry *route, - int vector, PCIDevice *dev) -{ - return 0; -} - -int kvm_arch_release_virq_post(int virq) -{ - return 0; -} - int kvm_arch_msi_data_to_gsi(uint32_t data) { abort(); diff --git a/target-s390x/machine.c b/target-s390x/machine.c index aa39e5daa..6b2609054 100644 --- a/target-s390x/machine.c +++ b/target-s390x/machine.c @@ -76,16 +76,6 @@ static const VMStateDescription vmstate_fpu = { } }; -static bool vregs_needed(void *opaque) -{ -#ifdef CONFIG_KVM - if (kvm_enabled()) { - return kvm_check_extension(kvm_state, KVM_CAP_S390_VECTOR_REGISTERS); - } -#endif - return 0; -} - static const VMStateDescription vmstate_vregs = { .name = "cpu/vregs", .version_id = 1, @@ -145,27 +135,6 @@ static const VMStateDescription vmstate_vregs = { } }; -static bool riccb_needed(void *opaque) -{ -#ifdef CONFIG_KVM - if (kvm_enabled()) { - return kvm_s390_get_ri(); - } -#endif - return 0; -} - -const VMStateDescription vmstate_riccb = { - .name = "cpu/riccb", - .version_id = 1, - .minimum_version_id = 1, - .needed = riccb_needed, - .fields = (VMStateField[]) { - VMSTATE_UINT8_ARRAY(env.riccb, S390CPU, 64), - VMSTATE_END_OF_LIST() - } -}; - const VMStateDescription vmstate_s390_cpu = { .name = "cpu", .post_load = cpu_post_load, @@ -197,7 +166,6 @@ const VMStateDescription vmstate_s390_cpu = { .subsections = (const VMStateDescription*[]) { &vmstate_fpu, &vmstate_vregs, - &vmstate_riccb, NULL }, }; diff --git a/target-s390x/mem_helper.c b/target-s390x/mem_helper.c index 99bc5e283..707862203 100644 --- a/target-s390x/mem_helper.c +++ b/target-s390x/mem_helper.c @@ -21,12 +21,8 @@ #include "qemu/osdep.h" #include "cpu.h" #include "exec/helper-proto.h" -#include "exec/exec-all.h" #include "exec/cpu_ldst.h" - -#if !defined(CONFIG_USER_ONLY) #include "hw/s390x/storage-keys.h" -#endif /*****************************************************************************/ /* Softmmu support */ @@ -36,12 +32,12 @@ NULL, it means that the function was called in C code (i.e. not from generated code or from helper.c) */ /* XXX: fix it to restore all registers */ -void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type, - int mmu_idx, uintptr_t retaddr) +void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx, + uintptr_t retaddr) { int ret; - ret = s390_cpu_handle_mmu_fault(cs, addr, access_type, mmu_idx); + ret = s390_cpu_handle_mmu_fault(cs, addr, is_write, mmu_idx); if (unlikely(ret != 0)) { if (likely(retaddr)) { /* now we have a real cpu fault */ diff --git a/target-s390x/misc_helper.c b/target-s390x/misc_helper.c index 86da1947b..71cbe34e0 100644 --- a/target-s390x/misc_helper.c +++ b/target-s390x/misc_helper.c @@ -29,11 +29,10 @@ #ifdef CONFIG_KVM #include <linux/kvm.h> #endif -#include "exec/exec-all.h" #include "exec/cpu_ldst.h" +#include "hw/watchdog/wdt_diag288.h" #if !defined(CONFIG_USER_ONLY) -#include "hw/watchdog/wdt_diag288.h" #include "sysemu/cpus.h" #include "sysemu/sysemu.h" #include "hw/s390x/ebcdic.h" @@ -233,23 +232,10 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3) program_interrupt(env, PGM_ADDRESSING, ILEN_LATER_INC); return; } - iplb = g_malloc0(sizeof(IplParameterBlock)); - cpu_physical_memory_read(addr, iplb, sizeof(iplb->len)); - if (!iplb_valid_len(iplb)) { - env->regs[r1 + 1] = DIAG_308_RC_INVALID; - goto out; - } - - cpu_physical_memory_read(addr, iplb, be32_to_cpu(iplb->len)); - - if (!iplb_valid_ccw(iplb) && !iplb_valid_fcp(iplb)) { - env->regs[r1 + 1] = DIAG_308_RC_INVALID; - goto out; - } - + iplb = g_malloc0(sizeof(struct IplParameterBlock)); + cpu_physical_memory_read(addr, iplb, sizeof(struct IplParameterBlock)); s390_ipl_update_diag308(iplb); env->regs[r1 + 1] = DIAG_308_RC_OK; -out: g_free(iplb); return; case 6: @@ -264,7 +250,8 @@ out: } iplb = s390_ipl_get_iplb(); if (iplb) { - cpu_physical_memory_write(addr, iplb, be32_to_cpu(iplb->len)); + cpu_physical_memory_write(addr, iplb, + sizeof(struct IplParameterBlock)); env->regs[r1 + 1] = DIAG_308_RC_OK; } else { env->regs[r1 + 1] = DIAG_308_RC_NO_CONF; diff --git a/target-s390x/trace-events b/target-s390x/trace-events deleted file mode 100644 index df59f5f19..000000000 --- a/target-s390x/trace-events +++ /dev/null @@ -1,22 +0,0 @@ -# See docs/tracing.txt for syntax documentation. - -# target-s390x/mmu_helper.c -get_skeys_nonzero(int rc) "SKEY: Call to get_skeys unexpectedly returned %d" -set_skeys_nonzero(int rc) "SKEY: Call to set_skeys unexpectedly returned %d" - -# target-s390x/ioinst.c -ioinst(const char *insn) "IOINST: %s" -ioinst_sch_id(const char *insn, int cssid, int ssid, int schid) "IOINST: %s (%x.%x.%04x)" -ioinst_chp_id(const char *insn, int cssid, int chpid) "IOINST: %s (%x.%02x)" -ioinst_chsc_cmd(uint16_t cmd, uint16_t len) "IOINST: chsc command %04x, len %04x" - -# target-s390x/kvm.c -kvm_enable_cmma(int rc) "CMMA: enabling with result code %d" -kvm_clear_cmma(int rc) "CMMA: clearing with result code %d" -kvm_failed_cpu_state_set(int cpu_index, uint8_t state, const char *msg) "Warning: Unable to set cpu %d state %" PRIu8 " to KVM: %s" -kvm_sigp_finished(uint8_t order, int cpu_index, int dst_index, int cc) "SIGP: Finished order %u on cpu %d -> cpu %d with cc=%d" - -# target-s390x/cpu.c -cpu_set_state(int cpu_index, uint8_t state) "setting cpu %d state to %" PRIu8 -cpu_halt(int cpu_index) "halting cpu %d" -cpu_unhalt(int cpu_index) "unhalting cpu %d" diff --git a/target-s390x/translate.c b/target-s390x/translate.c index 1a07d70b2..c871ef2bb 100644 --- a/target-s390x/translate.c +++ b/target-s390x/translate.c @@ -31,7 +31,6 @@ #include "qemu/osdep.h" #include "cpu.h" #include "disas/disas.h" -#include "exec/exec-all.h" #include "tcg-op.h" #include "qemu/log.h" #include "qemu/host-utils.h" @@ -169,7 +168,6 @@ void s390x_translate_init(void) int i; cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env"); - tcg_ctx.tcg_env = cpu_env; psw_addr = tcg_global_mem_new_i64(cpu_env, offsetof(CPUS390XState, psw.addr), "psw_addr"); @@ -610,17 +608,12 @@ static void gen_op_calc_cc(DisasContext *s) static int use_goto_tb(DisasContext *s, uint64_t dest) { - if (unlikely(s->singlestep_enabled) || - (s->tb->cflags & CF_LAST_IO) || - (s->tb->flags & FLAG_MASK_PER)) { - return false; - } -#ifndef CONFIG_USER_ONLY - return (dest & TARGET_PAGE_MASK) == (s->tb->pc & TARGET_PAGE_MASK) || - (dest & TARGET_PAGE_MASK) == (s->pc & TARGET_PAGE_MASK); -#else - return true; -#endif + /* NOTE: we handle the case where the TB spans two pages here */ + return (((dest & TARGET_PAGE_MASK) == (s->tb->pc & TARGET_PAGE_MASK) + || (dest & TARGET_PAGE_MASK) == ((s->pc - 1) & TARGET_PAGE_MASK)) + && !s->singlestep_enabled + && !(s->tb->cflags & CF_LAST_IO) + && !(s->tb->flags & FLAG_MASK_PER)); } static void account_noninline_branch(DisasContext *s, int cc_op) @@ -3986,21 +3979,21 @@ static ExitStatus op_svc(DisasContext *s, DisasOps *o) static ExitStatus op_tceb(DisasContext *s, DisasOps *o) { - gen_helper_tceb(cc_op, cpu_env, o->in1, o->in2); + gen_helper_tceb(cc_op, o->in1, o->in2); set_cc_static(s); return NO_EXIT; } static ExitStatus op_tcdb(DisasContext *s, DisasOps *o) { - gen_helper_tcdb(cc_op, cpu_env, o->in1, o->in2); + gen_helper_tcdb(cc_op, o->in1, o->in2); set_cc_static(s); return NO_EXIT; } static ExitStatus op_tcxb(DisasContext *s, DisasOps *o) { - gen_helper_tcxb(cc_op, cpu_env, o->out, o->out2, o->in2); + gen_helper_tcxb(cc_op, o->out, o->out2, o->in2); set_cc_static(s); return NO_EXIT; } @@ -5430,8 +5423,7 @@ void gen_intermediate_code(CPUS390XState *env, struct TranslationBlock *tb) tb->icount = num_insns; #if defined(S390X_DEBUG_DISAS) - if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) - && qemu_log_in_addr_range(pc_start)) { + if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { qemu_log("IN: %s\n", lookup_symbol(pc_start)); log_target_disas(cs, pc_start, dc.pc - pc_start, 1); qemu_log("\n"); |