Patch queue for s390 - 2013-12-18

This covers mostly minor bug fixes and implements the SIGP START
 hypercall which allows to start a remote CPU without changing its
 state.
 
 Cornelia Huck (1):
       s390x/kvm: Fix diagnose handling.
 
 Thomas Huth (7):
       s390x/kvm: Removed duplicated SIGP defines
       s390x/kvm: Removed s390_store_status stub
       s390x/kvm: Fix coding style in handle_sigp()
       s390x/kvm: Implemented SIGP START
       s390x/kvm: Simplified the calculation of the SIGP order code
       s390x/kvm: Fixed condition code for unknown SIGP orders
       s390x/ioinst: CHSC has to set a condition code
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.9 (GNU/Linux)
 
 iQIcBAABAgAGBQJSsaJUAAoJECszeR4D/txgVl8QAM5F95RFMx2HaCNzPIJjmXPC
 e5k1qdwYHdD6PjCky0/Z/B7+S+5VHVhWEkFBx0Ikj2sMW441xLgYnmE2ObuUL/p3
 jl8oOca4N5M7FiSYtXhNNP8VQKp5cNJaZGo+AD6NU8wyrtg0SiDfBl2pWHUMa/Bt
 Z5LatecOjdo5EL9cb0iNQ8mIYoxlkKpRp4AYAXTHQ43h26LDxLqpQnsZo/Sf5Z7R
 6heut7FptCuoIRaoO4Di7/VlDpUQXNKqkXFN0eeLkt3hsB/0FdBxK9VvtwzFmh1W
 HOfWW+9eqW3YJsVxtfFUO1T8ZmcI59SH7TnnURb6NKTW5eYhBO6u2hh6osjqhTka
 gDyp6mvca2/U/iM1YijjkNqM/KRZYDCtYQ70/UdqJj70qevmQGKCnZGrkrbfY6Sn
 GYC8LS3giYr6wdOex3+hnHAw5tXr+Sa2OfacjPMFgqJ832Fx9N9epPCEAUNqVhk2
 JRYvE4XXZd2GEdq0658RkDCEOwN+QDIrsHWwSNKjP9/8RkPFezb0PeFMFmPPhrWG
 ePRhTfTOAzTED4dxxvAajNXpUwzMCi1cqF34eg/mCH67Rs5MlS6QzSpTycRXXTDU
 YZuTlVw34NNhsYDFmpFOBdEEr6muDDuNpa1wi65BzxfNNPgdM0mvdPj4+sV91SOB
 mauLtI1UNLCp0aEkb6US
 =0Gfl
 -----END PGP SIGNATURE-----

Merge tag 'signed-s390-for-upstream' of git://github.com/agraf/qemu

Patch queue for s390 - 2013-12-18

This covers mostly minor bug fixes and implements the SIGP START
hypercall which allows to start a remote CPU without changing its
state.

Cornelia Huck (1):
      s390x/kvm: Fix diagnose handling.

Thomas Huth (7):
      s390x/kvm: Removed duplicated SIGP defines
      s390x/kvm: Removed s390_store_status stub
      s390x/kvm: Fix coding style in handle_sigp()
      s390x/kvm: Implemented SIGP START
      s390x/kvm: Simplified the calculation of the SIGP order code
      s390x/kvm: Fixed condition code for unknown SIGP orders
      s390x/ioinst: CHSC has to set a condition code

* tag 'signed-s390-for-upstream' of git://github.com/agraf/qemu:
  s390x/ioinst: CHSC has to set a condition code
  s390x/kvm: Fixed condition code for unknown SIGP orders
  s390x/kvm: Simplified the calculation of the SIGP order code
  s390x/kvm: Implemented SIGP START
  s390x/kvm: Fix coding style in handle_sigp()
  s390x/kvm: Removed s390_store_status stub
  s390x/kvm: Removed duplicated SIGP defines
  s390x/kvm: Fix diagnose handling.
This commit is contained in:
Aurelien Jarno 2013-12-21 16:46:07 +01:00
commit e8092f7ae1
3 changed files with 49 additions and 51 deletions

View File

@ -352,6 +352,9 @@ static inline hwaddr decode_basedisp_s(CPUS390XState *env, uint32_t ipb)
return addr; return addr;
} }
/* Base/displacement are at the same locations. */
#define decode_basedisp_rs decode_basedisp_s
void s390x_tod_timer(void *opaque); void s390x_tod_timer(void *opaque);
void s390x_cpu_timer(void *opaque); void s390x_cpu_timer(void *opaque);

View File

@ -622,6 +622,7 @@ void ioinst_handle_chsc(S390CPU *cpu, uint32_t ipb)
break; break;
} }
setcc(cpu, 0); /* Command execution complete */
out: out:
s390_cpu_physical_memory_unmap(env, req, map_size, 1); s390_cpu_physical_memory_unmap(env, req, map_size, 1);
} }

View File

@ -82,11 +82,6 @@
#define ICPT_CPU_STOP 0x28 #define ICPT_CPU_STOP 0x28
#define ICPT_IO 0x40 #define ICPT_IO 0x40
#define SIGP_RESTART 0x06
#define SIGP_INITIAL_CPU_RESET 0x0b
#define SIGP_STORE_STATUS_ADDR 0x0e
#define SIGP_SET_ARCH 0x12
const KVMCapabilityInfo kvm_arch_required_capabilities[] = { const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
KVM_CAP_LAST_INFO KVM_CAP_LAST_INFO
}; };
@ -562,11 +557,19 @@ static void kvm_handle_diag_308(S390CPU *cpu, struct kvm_run *run)
handle_diag_308(&cpu->env, r1, r3); handle_diag_308(&cpu->env, r1, r3);
} }
static int handle_diag(S390CPU *cpu, struct kvm_run *run, int ipb_code) #define DIAG_KVM_CODE_MASK 0x000000000000ffff
static int handle_diag(S390CPU *cpu, struct kvm_run *run, uint32_t ipb)
{ {
int r = 0; int r = 0;
uint16_t func_code;
switch (ipb_code) { /*
* For any diagnose call we support, bits 48-63 of the resulting
* address specify the function code; the remainder is ignored.
*/
func_code = decode_basedisp_rs(&cpu->env, ipb) & DIAG_KVM_CODE_MASK;
switch (func_code) {
case DIAG_IPL: case DIAG_IPL:
kvm_handle_diag_308(cpu, run); kvm_handle_diag_308(cpu, run);
break; break;
@ -577,7 +580,7 @@ static int handle_diag(S390CPU *cpu, struct kvm_run *run, int ipb_code)
sleep(10); sleep(10);
break; break;
default: default:
DPRINTF("KVM: unknown DIAG: 0x%x\n", ipb_code); DPRINTF("KVM: unknown DIAG: 0x%x\n", func_code);
r = -1; r = -1;
break; break;
} }
@ -585,6 +588,14 @@ static int handle_diag(S390CPU *cpu, struct kvm_run *run, int ipb_code)
return r; return r;
} }
static int kvm_s390_cpu_start(S390CPU *cpu)
{
s390_add_running_cpu(cpu);
qemu_cpu_kick(CPU(cpu));
DPRINTF("DONE: KVM cpu start: %p\n", &cpu->env);
return 0;
}
int kvm_s390_cpu_restart(S390CPU *cpu) int kvm_s390_cpu_restart(S390CPU *cpu)
{ {
kvm_s390_interrupt(cpu, KVM_S390_RESTART, 0); kvm_s390_interrupt(cpu, KVM_S390_RESTART, 0);
@ -594,13 +605,6 @@ int kvm_s390_cpu_restart(S390CPU *cpu)
return 0; return 0;
} }
static int s390_store_status(CPUS390XState *env, uint32_t parameter)
{
/* XXX */
fprintf(stderr, "XXX SIGP store status\n");
return -1;
}
static int s390_cpu_initial_reset(S390CPU *cpu) static int s390_cpu_initial_reset(S390CPU *cpu)
{ {
CPUState *cs = CPU(cpu); CPUState *cs = CPU(cpu);
@ -622,61 +626,52 @@ static int s390_cpu_initial_reset(S390CPU *cpu)
return 0; return 0;
} }
#define SIGP_ORDER_MASK 0x000000ff
static int handle_sigp(S390CPU *cpu, struct kvm_run *run, uint8_t ipa1) static int handle_sigp(S390CPU *cpu, struct kvm_run *run, uint8_t ipa1)
{ {
CPUS390XState *env = &cpu->env; CPUS390XState *env = &cpu->env;
uint8_t order_code; uint8_t order_code;
uint32_t parameter;
uint16_t cpu_addr; uint16_t cpu_addr;
uint8_t t;
int r = -1;
S390CPU *target_cpu; S390CPU *target_cpu;
CPUS390XState *target_env; uint64_t *statusreg = &env->regs[ipa1 >> 4];
int cc;
cpu_synchronize_state(CPU(cpu)); cpu_synchronize_state(CPU(cpu));
/* get order code */ /* get order code */
order_code = run->s390_sieic.ipb >> 28; order_code = decode_basedisp_rs(env, run->s390_sieic.ipb) & SIGP_ORDER_MASK;
if (order_code > 0) {
order_code = env->regs[order_code];
}
order_code += (run->s390_sieic.ipb & 0x0fff0000) >> 16;
/* get parameters */
t = (ipa1 & 0xf0) >> 4;
if (!(t % 2)) {
t++;
}
parameter = env->regs[t] & 0x7ffffe00;
cpu_addr = env->regs[ipa1 & 0x0f]; cpu_addr = env->regs[ipa1 & 0x0f];
target_cpu = s390_cpu_addr2state(cpu_addr); target_cpu = s390_cpu_addr2state(cpu_addr);
if (target_cpu == NULL) { if (target_cpu == NULL) {
cc = 3; /* not operational */
goto out; goto out;
} }
target_env = &target_cpu->env;
switch (order_code) { switch (order_code) {
case SIGP_RESTART: case SIGP_START:
r = kvm_s390_cpu_restart(target_cpu); cc = kvm_s390_cpu_start(target_cpu);
break; break;
case SIGP_STORE_STATUS_ADDR: case SIGP_RESTART:
r = s390_store_status(target_env, parameter); cc = kvm_s390_cpu_restart(target_cpu);
break; break;
case SIGP_SET_ARCH: case SIGP_SET_ARCH:
/* make the caller panic */ /* make the caller panic */
return -1; return -1;
case SIGP_INITIAL_CPU_RESET: case SIGP_INITIAL_CPU_RESET:
r = s390_cpu_initial_reset(target_cpu); cc = s390_cpu_initial_reset(target_cpu);
break; break;
default: default:
fprintf(stderr, "KVM: unknown SIGP: 0x%x\n", order_code); DPRINTF("KVM: unknown SIGP: 0x%x\n", order_code);
break; *statusreg &= 0xffffffff00000000UL;
*statusreg |= SIGP_STAT_INVALID_ORDER;
cc = 1; /* status stored */
break;
} }
out: out:
setcc(cpu, r ? 3 : 0); setcc(cpu, cc);
return 0; return 0;
} }
@ -684,7 +679,6 @@ static void handle_instruction(S390CPU *cpu, struct kvm_run *run)
{ {
unsigned int ipa0 = (run->s390_sieic.ipa & 0xff00); unsigned int ipa0 = (run->s390_sieic.ipa & 0xff00);
uint8_t ipa1 = run->s390_sieic.ipa & 0x00ff; uint8_t ipa1 = run->s390_sieic.ipa & 0x00ff;
int ipb_code = (run->s390_sieic.ipb & 0x0fff0000) >> 16;
int r = -1; int r = -1;
DPRINTF("handle_instruction 0x%x 0x%x\n", DPRINTF("handle_instruction 0x%x 0x%x\n",
@ -696,7 +690,7 @@ static void handle_instruction(S390CPU *cpu, struct kvm_run *run)
r = handle_priv(cpu, run, ipa0 >> 8, ipa1); r = handle_priv(cpu, run, ipa0 >> 8, ipa1);
break; break;
case IPA0_DIAG: case IPA0_DIAG:
r = handle_diag(cpu, run, ipb_code); r = handle_diag(cpu, run, run->s390_sieic.ipb);
break; break;
case IPA0_SIGP: case IPA0_SIGP:
r = handle_sigp(cpu, run, ipa1); r = handle_sigp(cpu, run, ipa1);