Skip to content

Commit

Permalink
s390x: Store Additional Status SIGP order
Browse files Browse the repository at this point in the history
Add handling for the Store Additional Status at Address order
that exists for the Signal Processor (SIGP) instruction.

Signed-off-by: Eric Farman <farman@linux.vnet.ibm.com>
Reviewed-by: Thomas Huth <thuth@linux.vnet.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
  • Loading branch information
Eric Farman authored and cohuck committed May 27, 2015
1 parent fcb7980 commit abec535
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 0 deletions.
1 change: 1 addition & 0 deletions target-s390x/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -945,6 +945,7 @@ struct sysib_322 {
#define SIGP_SET_PREFIX 0x0d
#define SIGP_STORE_STATUS_ADDR 0x0e
#define SIGP_SET_ARCH 0x12
#define SIGP_STORE_ADTL_STATUS 0x17

/* SIGP condition codes */
#define SIGP_CC_ORDER_CODE_ACCEPTED 0
Expand Down
55 changes: 55 additions & 0 deletions target-s390x/kvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1373,6 +1373,28 @@ static void sigp_stop(void *arg)
si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
}

#define ADTL_SAVE_AREA_SIZE 1024
static int kvm_s390_store_adtl_status(S390CPU *cpu, hwaddr addr)
{
void *mem;
hwaddr len = ADTL_SAVE_AREA_SIZE;

mem = cpu_physical_memory_map(addr, &len, 1);
if (!mem) {
return -EFAULT;
}
if (len != ADTL_SAVE_AREA_SIZE) {
cpu_physical_memory_unmap(mem, len, 1, 0);
return -EFAULT;
}

memcpy(mem, &cpu->env.vregs, 512);

cpu_physical_memory_unmap(mem, len, 1, len);

return 0;
}

#define KVM_S390_STORE_STATUS_DEF_ADDR offsetof(LowCore, floating_pt_save_area)
#define SAVE_AREA_SIZE 512
static int kvm_s390_store_status(S390CPU *cpu, hwaddr addr, bool store_arch)
Expand Down Expand Up @@ -1461,6 +1483,36 @@ static void sigp_store_status_at_address(void *arg)
si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
}

static void sigp_store_adtl_status(void *arg)
{
SigpInfo *si = arg;

if (!kvm_check_extension(kvm_state, KVM_CAP_S390_VECTOR_REGISTERS)) {
set_sigp_status(si, SIGP_STAT_INVALID_ORDER);
return;
}

/* cpu has to be stopped */
if (s390_cpu_get_state(si->cpu) != CPU_STATE_STOPPED) {
set_sigp_status(si, SIGP_STAT_INCORRECT_STATE);
return;
}

/* parameter must be aligned to 1024-byte boundary */
if (si->param & 0x3ff) {
set_sigp_status(si, SIGP_STAT_INVALID_PARAMETER);
return;
}

cpu_synchronize_state(CPU(si->cpu));

if (kvm_s390_store_adtl_status(si->cpu, si->param)) {
set_sigp_status(si, SIGP_STAT_INVALID_PARAMETER);
return;
}
si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
}

static void sigp_restart(void *arg)
{
SigpInfo *si = arg;
Expand Down Expand Up @@ -1578,6 +1630,9 @@ static int handle_sigp_single_dst(S390CPU *dst_cpu, uint8_t order,
case SIGP_STORE_STATUS_ADDR:
run_on_cpu(CPU(dst_cpu), sigp_store_status_at_address, &si);
break;
case SIGP_STORE_ADTL_STATUS:
run_on_cpu(CPU(dst_cpu), sigp_store_adtl_status, &si);
break;
case SIGP_SET_PREFIX:
run_on_cpu(CPU(dst_cpu), sigp_set_prefix, &si);
break;
Expand Down

0 comments on commit abec535

Please sign in to comment.