diff options
Diffstat (limited to 'target-s390x')
-rw-r--r-- | target-s390x/Makefile.objs | 5 | ||||
-rw-r--r-- | target-s390x/cpu.c | 2 | ||||
-rw-r--r-- | target-s390x/cpu.h | 10 | ||||
-rw-r--r-- | target-s390x/helper.c | 13 | ||||
-rw-r--r-- | target-s390x/kvm.c | 48 | ||||
-rw-r--r-- | target-s390x/translate.c | 2 |
6 files changed, 59 insertions, 21 deletions
diff --git a/target-s390x/Makefile.objs b/target-s390x/Makefile.objs new file mode 100644 index 0000000000..262747f8a6 --- /dev/null +++ b/target-s390x/Makefile.objs @@ -0,0 +1,5 @@ +obj-y += translate.o op_helper.o helper.o cpu.o +obj-$(CONFIG_SOFTMMU) += machine.o +obj-$(CONFIG_KVM) += kvm.o + +$(obj)/op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS) diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c index f183213eab..619b202b92 100644 --- a/target-s390x/cpu.c +++ b/target-s390x/cpu.c @@ -20,7 +20,7 @@ * <http://www.gnu.org/licenses/lgpl-2.1.html> */ -#include "cpu-qom.h" +#include "cpu.h" #include "qemu-common.h" #include "qemu-timer.h" diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h index 2f3f3942c0..c30ac3a0e1 100644 --- a/target-s390x/cpu.h +++ b/target-s390x/cpu.h @@ -105,6 +105,8 @@ typedef struct CPUS390XState { QEMUTimer *cpu_timer; } CPUS390XState; +#include "cpu-qom.h" + #if defined(CONFIG_USER_ONLY) static inline void cpu_clone_regs(CPUS390XState *env, target_ulong newsp) { @@ -271,7 +273,7 @@ static inline int get_ilc(uint8_t opc) #define ILC_LATER_INC_2 0x22 -CPUS390XState *cpu_s390x_init(const char *cpu_model); +S390CPU *cpu_s390x_init(const char *cpu_model); void s390x_translate_init(void); int cpu_s390x_exec(CPUS390XState *s); void cpu_s390x_close(CPUS390XState *s); @@ -314,7 +316,7 @@ static inline void kvm_s390_interrupt_internal(CPUS390XState *env, int type, { } #endif -CPUS390XState *s390_cpu_addr2state(uint16_t cpu_addr); +S390CPU *s390_cpu_addr2state(uint16_t cpu_addr); void s390_add_running_cpu(CPUS390XState *env); unsigned s390_del_running_cpu(CPUS390XState *env); @@ -340,7 +342,7 @@ static inline void cpu_set_tls(CPUS390XState *env, target_ulong newtls) env->aregs[1] = newtls & 0xffffffffULL; } -#define cpu_init cpu_s390x_init +#define cpu_init(model) (&cpu_s390x_init(model)->env) #define cpu_exec cpu_s390x_exec #define cpu_gen_code cpu_s390x_gen_code #define cpu_signal_handler cpu_s390x_signal_handler @@ -994,6 +996,4 @@ static inline void cpu_pc_from_tb(CPUS390XState *env, TranslationBlock* tb) env->psw.addr = tb->pc; } -#include "cpu-qom.h" - #endif diff --git a/target-s390x/helper.c b/target-s390x/helper.c index 209a69603c..d0a1180a83 100644 --- a/target-s390x/helper.c +++ b/target-s390x/helper.c @@ -70,7 +70,7 @@ void s390x_cpu_timer(void *opaque) } #endif -CPUS390XState *cpu_s390x_init(const char *cpu_model) +S390CPU *cpu_s390x_init(const char *cpu_model) { S390CPU *cpu; CPUS390XState *env; @@ -86,7 +86,7 @@ CPUS390XState *cpu_s390x_init(const char *cpu_model) env->cpu_model_str = cpu_model; qemu_init_vcpu(env); - return env; + return cpu; } #if defined(CONFIG_USER_ONLY) @@ -106,14 +106,7 @@ int cpu_s390x_handle_mmu_fault (CPUS390XState *env, target_ulong address, int rw return 1; } -#endif /* CONFIG_USER_ONLY */ - -void cpu_state_reset(CPUS390XState *env) -{ - cpu_reset(ENV_GET_CPU(env)); -} - -#ifndef CONFIG_USER_ONLY +#else /* !CONFIG_USER_ONLY */ /* Ensure to exit the TB after this call! */ static void trigger_pgm_exception(CPUS390XState *env, uint32_t code, uint32_t ilc) diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c index 90aad61eb0..47008c24f2 100644 --- a/target-s390x/kvm.c +++ b/target-s390x/kvm.c @@ -135,6 +135,41 @@ int kvm_arch_get_registers(CPUS390XState *env) return 0; } +/* + * Legacy layout for s390: + * Older S390 KVM requires the topmost vma of the RAM to be + * smaller than an system defined value, which is at least 256GB. + * Larger systems have larger values. We put the guest between + * the end of data segment (system break) and this value. We + * use 32GB as a base to have enough room for the system break + * to grow. We also have to use MAP parameters that avoid + * read-only mapping of guest pages. + */ +static void *legacy_s390_alloc(ram_addr_t size) +{ + void *mem; + + mem = mmap((void *) 0x800000000ULL, size, + PROT_EXEC|PROT_READ|PROT_WRITE, + MAP_SHARED | MAP_ANONYMOUS | MAP_FIXED, -1, 0); + if (mem == MAP_FAILED) { + fprintf(stderr, "Allocating RAM failed\n"); + abort(); + } + return mem; +} + +void *kvm_arch_vmalloc(ram_addr_t size) +{ + /* Can we use the standard allocation ? */ + if (kvm_check_extension(kvm_state, KVM_CAP_S390_GMAP) && + kvm_check_extension(kvm_state, KVM_CAP_S390_COW)) { + return NULL; + } else { + return legacy_s390_alloc(size); + } +} + int kvm_arch_insert_sw_breakpoint(CPUS390XState *env, struct kvm_sw_breakpoint *bp) { static const uint8_t diag_501[] = {0x83, 0x24, 0x05, 0x01}; @@ -292,8 +327,10 @@ static int handle_diag(CPUS390XState *env, struct kvm_run *run, int ipb_code) return r; } -static int s390_cpu_restart(CPUS390XState *env) +static int s390_cpu_restart(S390CPU *cpu) { + CPUS390XState *env = &cpu->env; + kvm_s390_interrupt(env, KVM_S390_RESTART, 0); s390_add_running_cpu(env); qemu_cpu_kick(env); @@ -312,6 +349,7 @@ static int s390_cpu_initial_reset(CPUS390XState *env) { int i; + s390_del_running_cpu(env); if (kvm_vcpu_ioctl(env, KVM_S390_INITIAL_RESET, NULL) < 0) { perror("cannot init reset vcpu"); } @@ -333,6 +371,7 @@ static int handle_sigp(CPUS390XState *env, struct kvm_run *run, uint8_t ipa1) uint16_t cpu_addr; uint8_t t; int r = -1; + S390CPU *target_cpu; CPUS390XState *target_env; cpu_synchronize_state(env); @@ -353,14 +392,15 @@ static int handle_sigp(CPUS390XState *env, struct kvm_run *run, uint8_t ipa1) parameter = env->regs[t] & 0x7ffffe00; cpu_addr = env->regs[ipa1 & 0x0f]; - target_env = s390_cpu_addr2state(cpu_addr); - if (!target_env) { + target_cpu = s390_cpu_addr2state(cpu_addr); + if (target_cpu == NULL) { goto out; } + target_env = &target_cpu->env; switch (order_code) { case SIGP_RESTART: - r = s390_cpu_restart(target_env); + r = s390_cpu_restart(target_cpu); break; case SIGP_STORE_STATUS_ADDR: r = s390_store_status(target_env, parameter); diff --git a/target-s390x/translate.c b/target-s390x/translate.c index 9bf8c38bb3..1c1baf5342 100644 --- a/target-s390x/translate.c +++ b/target-s390x/translate.c @@ -5098,7 +5098,7 @@ static void disas_s390_insn(DisasContext *s) disas_ed(s, op, r1, x2, b2, d2, r1b); break; default: - LOG_DISAS("unimplemented opcode 0x%x\n", opc); + qemu_log_mask(LOG_UNIMP, "unimplemented opcode 0x%x\n", opc); gen_illegal_opcode(s, ilc); break; } |