提交 5d9bf1c0 编写于 作者: T Thomas Huth 提交者: Christian Borntraeger

s390/ioinst: Moved the CC setting to the IO instruction handlers

The IO instruction handlers now take care of setting the CC value on
their own, so that the confusing return code magic in kvm_handle_css_inst()
is not needed anymore.
Signed-off-by: NThomas Huth <thuth@linux.vnet.ibm.com>
Reviewed-by: NCornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: NChristian Borntraeger <borntraeger@de.ibm.com>
上级 3d0a615f
...@@ -36,7 +36,7 @@ int ioinst_disassemble_sch_ident(uint32_t value, int *m, int *cssid, int *ssid, ...@@ -36,7 +36,7 @@ int ioinst_disassemble_sch_ident(uint32_t value, int *m, int *cssid, int *ssid,
return 0; return 0;
} }
int ioinst_handle_xsch(CPUS390XState *env, uint64_t reg1) void ioinst_handle_xsch(S390CPU *cpu, uint64_t reg1)
{ {
int cssid, ssid, schid, m; int cssid, ssid, schid, m;
SubchDev *sch; SubchDev *sch;
...@@ -44,8 +44,8 @@ int ioinst_handle_xsch(CPUS390XState *env, uint64_t reg1) ...@@ -44,8 +44,8 @@ int ioinst_handle_xsch(CPUS390XState *env, uint64_t reg1)
int cc; int cc;
if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid)) { if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid)) {
program_interrupt(env, PGM_OPERAND, 2); program_interrupt(&cpu->env, PGM_OPERAND, 2);
return -EIO; return;
} }
trace_ioinst_sch_id("xsch", cssid, ssid, schid); trace_ioinst_sch_id("xsch", cssid, ssid, schid);
sch = css_find_subch(m, cssid, ssid, schid); sch = css_find_subch(m, cssid, ssid, schid);
...@@ -66,11 +66,10 @@ int ioinst_handle_xsch(CPUS390XState *env, uint64_t reg1) ...@@ -66,11 +66,10 @@ int ioinst_handle_xsch(CPUS390XState *env, uint64_t reg1)
cc = 1; cc = 1;
break; break;
} }
setcc(cpu, cc);
return cc;
} }
int ioinst_handle_csch(CPUS390XState *env, uint64_t reg1) void ioinst_handle_csch(S390CPU *cpu, uint64_t reg1)
{ {
int cssid, ssid, schid, m; int cssid, ssid, schid, m;
SubchDev *sch; SubchDev *sch;
...@@ -78,8 +77,8 @@ int ioinst_handle_csch(CPUS390XState *env, uint64_t reg1) ...@@ -78,8 +77,8 @@ int ioinst_handle_csch(CPUS390XState *env, uint64_t reg1)
int cc; int cc;
if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid)) { if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid)) {
program_interrupt(env, PGM_OPERAND, 2); program_interrupt(&cpu->env, PGM_OPERAND, 2);
return -EIO; return;
} }
trace_ioinst_sch_id("csch", cssid, ssid, schid); trace_ioinst_sch_id("csch", cssid, ssid, schid);
sch = css_find_subch(m, cssid, ssid, schid); sch = css_find_subch(m, cssid, ssid, schid);
...@@ -91,10 +90,10 @@ int ioinst_handle_csch(CPUS390XState *env, uint64_t reg1) ...@@ -91,10 +90,10 @@ int ioinst_handle_csch(CPUS390XState *env, uint64_t reg1)
} else { } else {
cc = 0; cc = 0;
} }
return cc; setcc(cpu, cc);
} }
int ioinst_handle_hsch(CPUS390XState *env, uint64_t reg1) void ioinst_handle_hsch(S390CPU *cpu, uint64_t reg1)
{ {
int cssid, ssid, schid, m; int cssid, ssid, schid, m;
SubchDev *sch; SubchDev *sch;
...@@ -102,8 +101,8 @@ int ioinst_handle_hsch(CPUS390XState *env, uint64_t reg1) ...@@ -102,8 +101,8 @@ int ioinst_handle_hsch(CPUS390XState *env, uint64_t reg1)
int cc; int cc;
if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid)) { if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid)) {
program_interrupt(env, PGM_OPERAND, 2); program_interrupt(&cpu->env, PGM_OPERAND, 2);
return -EIO; return;
} }
trace_ioinst_sch_id("hsch", cssid, ssid, schid); trace_ioinst_sch_id("hsch", cssid, ssid, schid);
sch = css_find_subch(m, cssid, ssid, schid); sch = css_find_subch(m, cssid, ssid, schid);
...@@ -124,8 +123,7 @@ int ioinst_handle_hsch(CPUS390XState *env, uint64_t reg1) ...@@ -124,8 +123,7 @@ int ioinst_handle_hsch(CPUS390XState *env, uint64_t reg1)
cc = 1; cc = 1;
break; break;
} }
setcc(cpu, cc);
return cc;
} }
static int ioinst_schib_valid(SCHIB *schib) static int ioinst_schib_valid(SCHIB *schib)
...@@ -141,7 +139,7 @@ static int ioinst_schib_valid(SCHIB *schib) ...@@ -141,7 +139,7 @@ static int ioinst_schib_valid(SCHIB *schib)
return 1; return 1;
} }
int ioinst_handle_msch(CPUS390XState *env, uint64_t reg1, uint32_t ipb) void ioinst_handle_msch(S390CPU *cpu, uint64_t reg1, uint32_t ipb)
{ {
int cssid, ssid, schid, m; int cssid, ssid, schid, m;
SubchDev *sch; SubchDev *sch;
...@@ -150,22 +148,21 @@ int ioinst_handle_msch(CPUS390XState *env, uint64_t reg1, uint32_t ipb) ...@@ -150,22 +148,21 @@ int ioinst_handle_msch(CPUS390XState *env, uint64_t reg1, uint32_t ipb)
int ret = -ENODEV; int ret = -ENODEV;
int cc; int cc;
hwaddr len = sizeof(*schib); hwaddr len = sizeof(*schib);
CPUS390XState *env = &cpu->env;
addr = decode_basedisp_s(env, ipb); addr = decode_basedisp_s(env, ipb);
if (addr & 3) { if (addr & 3) {
program_interrupt(env, PGM_SPECIFICATION, 2); program_interrupt(env, PGM_SPECIFICATION, 2);
return -EIO; return;
} }
schib = s390_cpu_physical_memory_map(env, addr, &len, 0); schib = s390_cpu_physical_memory_map(env, addr, &len, 0);
if (!schib || len != sizeof(*schib)) { if (!schib || len != sizeof(*schib)) {
program_interrupt(env, PGM_ADDRESSING, 2); program_interrupt(env, PGM_ADDRESSING, 2);
cc = -EIO;
goto out; goto out;
} }
if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid) || if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid) ||
!ioinst_schib_valid(schib)) { !ioinst_schib_valid(schib)) {
program_interrupt(env, PGM_OPERAND, 2); program_interrupt(env, PGM_OPERAND, 2);
cc = -EIO;
goto out; goto out;
} }
trace_ioinst_sch_id("msch", cssid, ssid, schid); trace_ioinst_sch_id("msch", cssid, ssid, schid);
...@@ -187,9 +184,10 @@ int ioinst_handle_msch(CPUS390XState *env, uint64_t reg1, uint32_t ipb) ...@@ -187,9 +184,10 @@ int ioinst_handle_msch(CPUS390XState *env, uint64_t reg1, uint32_t ipb)
cc = 1; cc = 1;
break; break;
} }
setcc(cpu, cc);
out: out:
s390_cpu_physical_memory_unmap(env, schib, len, 0); s390_cpu_physical_memory_unmap(env, schib, len, 0);
return cc;
} }
static void copy_orb_from_guest(ORB *dest, const ORB *src) static void copy_orb_from_guest(ORB *dest, const ORB *src)
...@@ -213,7 +211,7 @@ static int ioinst_orb_valid(ORB *orb) ...@@ -213,7 +211,7 @@ static int ioinst_orb_valid(ORB *orb)
return 1; return 1;
} }
int ioinst_handle_ssch(CPUS390XState *env, uint64_t reg1, uint32_t ipb) void ioinst_handle_ssch(S390CPU *cpu, uint64_t reg1, uint32_t ipb)
{ {
int cssid, ssid, schid, m; int cssid, ssid, schid, m;
SubchDev *sch; SubchDev *sch;
...@@ -222,23 +220,22 @@ int ioinst_handle_ssch(CPUS390XState *env, uint64_t reg1, uint32_t ipb) ...@@ -222,23 +220,22 @@ int ioinst_handle_ssch(CPUS390XState *env, uint64_t reg1, uint32_t ipb)
int ret = -ENODEV; int ret = -ENODEV;
int cc; int cc;
hwaddr len = sizeof(*orig_orb); hwaddr len = sizeof(*orig_orb);
CPUS390XState *env = &cpu->env;
addr = decode_basedisp_s(env, ipb); addr = decode_basedisp_s(env, ipb);
if (addr & 3) { if (addr & 3) {
program_interrupt(env, PGM_SPECIFICATION, 2); program_interrupt(env, PGM_SPECIFICATION, 2);
return -EIO; return;
} }
orig_orb = s390_cpu_physical_memory_map(env, addr, &len, 0); orig_orb = s390_cpu_physical_memory_map(env, addr, &len, 0);
if (!orig_orb || len != sizeof(*orig_orb)) { if (!orig_orb || len != sizeof(*orig_orb)) {
program_interrupt(env, PGM_ADDRESSING, 2); program_interrupt(env, PGM_ADDRESSING, 2);
cc = -EIO;
goto out; goto out;
} }
copy_orb_from_guest(&orb, orig_orb); copy_orb_from_guest(&orb, orig_orb);
if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid) || if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid) ||
!ioinst_orb_valid(&orb)) { !ioinst_orb_valid(&orb)) {
program_interrupt(env, PGM_OPERAND, 2); program_interrupt(env, PGM_OPERAND, 2);
cc = -EIO;
goto out; goto out;
} }
trace_ioinst_sch_id("ssch", cssid, ssid, schid); trace_ioinst_sch_id("ssch", cssid, ssid, schid);
...@@ -260,38 +257,39 @@ int ioinst_handle_ssch(CPUS390XState *env, uint64_t reg1, uint32_t ipb) ...@@ -260,38 +257,39 @@ int ioinst_handle_ssch(CPUS390XState *env, uint64_t reg1, uint32_t ipb)
cc = 1; cc = 1;
break; break;
} }
setcc(cpu, cc);
out: out:
s390_cpu_physical_memory_unmap(env, orig_orb, len, 0); s390_cpu_physical_memory_unmap(env, orig_orb, len, 0);
return cc;
} }
int ioinst_handle_stcrw(CPUS390XState *env, uint32_t ipb) void ioinst_handle_stcrw(S390CPU *cpu, uint32_t ipb)
{ {
CRW *crw; CRW *crw;
uint64_t addr; uint64_t addr;
int cc; int cc;
hwaddr len = sizeof(*crw); hwaddr len = sizeof(*crw);
CPUS390XState *env = &cpu->env;
addr = decode_basedisp_s(env, ipb); addr = decode_basedisp_s(env, ipb);
if (addr & 3) { if (addr & 3) {
program_interrupt(env, PGM_SPECIFICATION, 2); program_interrupt(env, PGM_SPECIFICATION, 2);
return -EIO; return;
} }
crw = s390_cpu_physical_memory_map(env, addr, &len, 1); crw = s390_cpu_physical_memory_map(env, addr, &len, 1);
if (!crw || len != sizeof(*crw)) { if (!crw || len != sizeof(*crw)) {
program_interrupt(env, PGM_ADDRESSING, 2); program_interrupt(env, PGM_ADDRESSING, 2);
cc = -EIO;
goto out; goto out;
} }
cc = css_do_stcrw(crw); cc = css_do_stcrw(crw);
/* 0 - crw stored, 1 - zeroes stored */ /* 0 - crw stored, 1 - zeroes stored */
setcc(cpu, cc);
out: out:
s390_cpu_physical_memory_unmap(env, crw, len, 1); s390_cpu_physical_memory_unmap(env, crw, len, 1);
return cc;
} }
int ioinst_handle_stsch(CPUS390XState *env, uint64_t reg1, uint32_t ipb) void ioinst_handle_stsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb)
{ {
int cssid, ssid, schid, m; int cssid, ssid, schid, m;
SubchDev *sch; SubchDev *sch;
...@@ -299,22 +297,21 @@ int ioinst_handle_stsch(CPUS390XState *env, uint64_t reg1, uint32_t ipb) ...@@ -299,22 +297,21 @@ int ioinst_handle_stsch(CPUS390XState *env, uint64_t reg1, uint32_t ipb)
int cc; int cc;
SCHIB *schib; SCHIB *schib;
hwaddr len = sizeof(*schib); hwaddr len = sizeof(*schib);
CPUS390XState *env = &cpu->env;
addr = decode_basedisp_s(env, ipb); addr = decode_basedisp_s(env, ipb);
if (addr & 3) { if (addr & 3) {
program_interrupt(env, PGM_SPECIFICATION, 2); program_interrupt(env, PGM_SPECIFICATION, 2);
return -EIO; return;
} }
schib = s390_cpu_physical_memory_map(env, addr, &len, 1); schib = s390_cpu_physical_memory_map(env, addr, &len, 1);
if (!schib || len != sizeof(*schib)) { if (!schib || len != sizeof(*schib)) {
program_interrupt(env, PGM_ADDRESSING, 2); program_interrupt(env, PGM_ADDRESSING, 2);
cc = -EIO;
goto out; goto out;
} }
if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid)) { if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid)) {
program_interrupt(env, PGM_OPERAND, 2); program_interrupt(env, PGM_OPERAND, 2);
cc = -EIO;
goto out; goto out;
} }
trace_ioinst_sch_id("stsch", cssid, ssid, schid); trace_ioinst_sch_id("stsch", cssid, ssid, schid);
...@@ -336,9 +333,10 @@ int ioinst_handle_stsch(CPUS390XState *env, uint64_t reg1, uint32_t ipb) ...@@ -336,9 +333,10 @@ int ioinst_handle_stsch(CPUS390XState *env, uint64_t reg1, uint32_t ipb)
cc = 0; cc = 0;
} }
} }
setcc(cpu, cc);
out: out:
s390_cpu_physical_memory_unmap(env, schib, len, 1); s390_cpu_physical_memory_unmap(env, schib, len, 1);
return cc;
} }
int ioinst_handle_tsch(CPUS390XState *env, uint64_t reg1, uint32_t ipb) int ioinst_handle_tsch(CPUS390XState *env, uint64_t reg1, uint32_t ipb)
...@@ -575,7 +573,7 @@ static void ioinst_handle_chsc_unimplemented(ChscResp *res) ...@@ -575,7 +573,7 @@ static void ioinst_handle_chsc_unimplemented(ChscResp *res)
res->param = 0; res->param = 0;
} }
int ioinst_handle_chsc(CPUS390XState *env, uint32_t ipb) void ioinst_handle_chsc(S390CPU *cpu, uint32_t ipb)
{ {
ChscReq *req; ChscReq *req;
ChscResp *res; ChscResp *res;
...@@ -584,7 +582,7 @@ int ioinst_handle_chsc(CPUS390XState *env, uint32_t ipb) ...@@ -584,7 +582,7 @@ int ioinst_handle_chsc(CPUS390XState *env, uint32_t ipb)
uint16_t len; uint16_t len;
uint16_t command; uint16_t command;
hwaddr map_size = TARGET_PAGE_SIZE; hwaddr map_size = TARGET_PAGE_SIZE;
int ret = 0; CPUS390XState *env = &cpu->env;
trace_ioinst("chsc"); trace_ioinst("chsc");
reg = (ipb >> 20) & 0x00f; reg = (ipb >> 20) & 0x00f;
...@@ -592,19 +590,17 @@ int ioinst_handle_chsc(CPUS390XState *env, uint32_t ipb) ...@@ -592,19 +590,17 @@ int ioinst_handle_chsc(CPUS390XState *env, uint32_t ipb)
/* Page boundary? */ /* Page boundary? */
if (addr & 0xfff) { if (addr & 0xfff) {
program_interrupt(env, PGM_SPECIFICATION, 2); program_interrupt(env, PGM_SPECIFICATION, 2);
return -EIO; return;
} }
req = s390_cpu_physical_memory_map(env, addr, &map_size, 1); req = s390_cpu_physical_memory_map(env, addr, &map_size, 1);
if (!req || map_size != TARGET_PAGE_SIZE) { if (!req || map_size != TARGET_PAGE_SIZE) {
program_interrupt(env, PGM_ADDRESSING, 2); program_interrupt(env, PGM_ADDRESSING, 2);
ret = -EIO;
goto out; goto out;
} }
len = be16_to_cpu(req->len); len = be16_to_cpu(req->len);
/* Length field valid? */ /* Length field valid? */
if ((len < 16) || (len > 4088) || (len & 7)) { if ((len < 16) || (len > 4088) || (len & 7)) {
program_interrupt(env, PGM_OPERAND, 2); program_interrupt(env, PGM_OPERAND, 2);
ret = -EIO;
goto out; goto out;
} }
memset((char *)req + len, 0, TARGET_PAGE_SIZE - len); memset((char *)req + len, 0, TARGET_PAGE_SIZE - len);
...@@ -628,7 +624,6 @@ int ioinst_handle_chsc(CPUS390XState *env, uint32_t ipb) ...@@ -628,7 +624,6 @@ int ioinst_handle_chsc(CPUS390XState *env, uint32_t ipb)
out: out:
s390_cpu_physical_memory_unmap(env, req, map_size, 1); s390_cpu_physical_memory_unmap(env, req, map_size, 1);
return ret;
} }
int ioinst_handle_tpi(CPUS390XState *env, uint32_t ipb) int ioinst_handle_tpi(CPUS390XState *env, uint32_t ipb)
...@@ -666,18 +661,19 @@ out: ...@@ -666,18 +661,19 @@ out:
#define SCHM_REG1_UPD(_reg) ((_reg & 0x0000000000000002) >> 1) #define SCHM_REG1_UPD(_reg) ((_reg & 0x0000000000000002) >> 1)
#define SCHM_REG1_DCT(_reg) (_reg & 0x0000000000000001) #define SCHM_REG1_DCT(_reg) (_reg & 0x0000000000000001)
int ioinst_handle_schm(CPUS390XState *env, uint64_t reg1, uint64_t reg2, void ioinst_handle_schm(S390CPU *cpu, uint64_t reg1, uint64_t reg2,
uint32_t ipb) uint32_t ipb)
{ {
uint8_t mbk; uint8_t mbk;
int update; int update;
int dct; int dct;
CPUS390XState *env = &cpu->env;
trace_ioinst("schm"); trace_ioinst("schm");
if (SCHM_REG1_RES(reg1)) { if (SCHM_REG1_RES(reg1)) {
program_interrupt(env, PGM_OPERAND, 2); program_interrupt(env, PGM_OPERAND, 2);
return -EIO; return;
} }
mbk = SCHM_REG1_MBK(reg1); mbk = SCHM_REG1_MBK(reg1);
...@@ -686,15 +682,13 @@ int ioinst_handle_schm(CPUS390XState *env, uint64_t reg1, uint64_t reg2, ...@@ -686,15 +682,13 @@ int ioinst_handle_schm(CPUS390XState *env, uint64_t reg1, uint64_t reg2,
if (update && (reg2 & 0x000000000000001f)) { if (update && (reg2 & 0x000000000000001f)) {
program_interrupt(env, PGM_OPERAND, 2); program_interrupt(env, PGM_OPERAND, 2);
return -EIO; return;
} }
css_do_schm(mbk, update, dct, update ? reg2 : 0); css_do_schm(mbk, update, dct, update ? reg2 : 0);
return 0;
} }
int ioinst_handle_rsch(CPUS390XState *env, uint64_t reg1) void ioinst_handle_rsch(S390CPU *cpu, uint64_t reg1)
{ {
int cssid, ssid, schid, m; int cssid, ssid, schid, m;
SubchDev *sch; SubchDev *sch;
...@@ -702,8 +696,8 @@ int ioinst_handle_rsch(CPUS390XState *env, uint64_t reg1) ...@@ -702,8 +696,8 @@ int ioinst_handle_rsch(CPUS390XState *env, uint64_t reg1)
int cc; int cc;
if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid)) { if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid)) {
program_interrupt(env, PGM_OPERAND, 2); program_interrupt(&cpu->env, PGM_OPERAND, 2);
return -EIO; return;
} }
trace_ioinst_sch_id("rsch", cssid, ssid, schid); trace_ioinst_sch_id("rsch", cssid, ssid, schid);
sch = css_find_subch(m, cssid, ssid, schid); sch = css_find_subch(m, cssid, ssid, schid);
...@@ -724,24 +718,23 @@ int ioinst_handle_rsch(CPUS390XState *env, uint64_t reg1) ...@@ -724,24 +718,23 @@ int ioinst_handle_rsch(CPUS390XState *env, uint64_t reg1)
cc = 1; cc = 1;
break; break;
} }
setcc(cpu, cc);
return cc;
} }
#define RCHP_REG1_RES(_reg) (_reg & 0x00000000ff00ff00) #define RCHP_REG1_RES(_reg) (_reg & 0x00000000ff00ff00)
#define RCHP_REG1_CSSID(_reg) ((_reg & 0x0000000000ff0000) >> 16) #define RCHP_REG1_CSSID(_reg) ((_reg & 0x0000000000ff0000) >> 16)
#define RCHP_REG1_CHPID(_reg) (_reg & 0x00000000000000ff) #define RCHP_REG1_CHPID(_reg) (_reg & 0x00000000000000ff)
int ioinst_handle_rchp(CPUS390XState *env, uint64_t reg1) void ioinst_handle_rchp(S390CPU *cpu, uint64_t reg1)
{ {
int cc; int cc;
uint8_t cssid; uint8_t cssid;
uint8_t chpid; uint8_t chpid;
int ret; int ret;
CPUS390XState *env = &cpu->env;
if (RCHP_REG1_RES(reg1)) { if (RCHP_REG1_RES(reg1)) {
program_interrupt(env, PGM_OPERAND, 2); program_interrupt(env, PGM_OPERAND, 2);
return -EIO; return;
} }
cssid = RCHP_REG1_CSSID(reg1); cssid = RCHP_REG1_CSSID(reg1);
...@@ -764,19 +757,16 @@ int ioinst_handle_rchp(CPUS390XState *env, uint64_t reg1) ...@@ -764,19 +757,16 @@ int ioinst_handle_rchp(CPUS390XState *env, uint64_t reg1)
default: default:
/* Invalid channel subsystem. */ /* Invalid channel subsystem. */
program_interrupt(env, PGM_OPERAND, 2); program_interrupt(env, PGM_OPERAND, 2);
return -EIO; return;
} }
setcc(cpu, cc);
return cc;
} }
#define SAL_REG1_INVALID(_reg) (_reg & 0x0000000080000000) #define SAL_REG1_INVALID(_reg) (_reg & 0x0000000080000000)
int ioinst_handle_sal(CPUS390XState *env, uint64_t reg1) void ioinst_handle_sal(S390CPU *cpu, uint64_t reg1)
{ {
/* We do not provide address limit checking, so let's suppress it. */ /* We do not provide address limit checking, so let's suppress it. */
if (SAL_REG1_INVALID(reg1) || reg1 & 0x000000000000ffff) { if (SAL_REG1_INVALID(reg1) || reg1 & 0x000000000000ffff) {
program_interrupt(env, PGM_OPERAND, 2); program_interrupt(&cpu->env, PGM_OPERAND, 2);
return -EIO;
} }
return 0;
} }
...@@ -214,20 +214,20 @@ typedef struct IOIntCode { ...@@ -214,20 +214,20 @@ typedef struct IOIntCode {
int ioinst_disassemble_sch_ident(uint32_t value, int *m, int *cssid, int *ssid, int ioinst_disassemble_sch_ident(uint32_t value, int *m, int *cssid, int *ssid,
int *schid); int *schid);
int ioinst_handle_xsch(CPUS390XState *env, uint64_t reg1); void ioinst_handle_xsch(S390CPU *cpu, uint64_t reg1);
int ioinst_handle_csch(CPUS390XState *env, uint64_t reg1); void ioinst_handle_csch(S390CPU *cpu, uint64_t reg1);
int ioinst_handle_hsch(CPUS390XState *env, uint64_t reg1); void ioinst_handle_hsch(S390CPU *cpu, uint64_t reg1);
int ioinst_handle_msch(CPUS390XState *env, uint64_t reg1, uint32_t ipb); void ioinst_handle_msch(S390CPU *cpu, uint64_t reg1, uint32_t ipb);
int ioinst_handle_ssch(CPUS390XState *env, uint64_t reg1, uint32_t ipb); void ioinst_handle_ssch(S390CPU *cpu, uint64_t reg1, uint32_t ipb);
int ioinst_handle_stcrw(CPUS390XState *env, uint32_t ipb); void ioinst_handle_stcrw(S390CPU *cpu, uint32_t ipb);
int ioinst_handle_stsch(CPUS390XState *env, uint64_t reg1, uint32_t ipb); void ioinst_handle_stsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb);
int ioinst_handle_tsch(CPUS390XState *env, uint64_t reg1, uint32_t ipb); int ioinst_handle_tsch(CPUS390XState *env, uint64_t reg1, uint32_t ipb);
int ioinst_handle_chsc(CPUS390XState *env, uint32_t ipb); void ioinst_handle_chsc(S390CPU *cpu, uint32_t ipb);
int ioinst_handle_tpi(CPUS390XState *env, uint32_t ipb); int ioinst_handle_tpi(CPUS390XState *env, uint32_t ipb);
int ioinst_handle_schm(CPUS390XState *env, uint64_t reg1, uint64_t reg2, void ioinst_handle_schm(S390CPU *cpu, uint64_t reg1, uint64_t reg2,
uint32_t ipb); uint32_t ipb);
int ioinst_handle_rsch(CPUS390XState *env, uint64_t reg1); void ioinst_handle_rsch(S390CPU *cpu, uint64_t reg1);
int ioinst_handle_rchp(CPUS390XState *env, uint64_t reg1); void ioinst_handle_rchp(S390CPU *cpu, uint64_t reg1);
int ioinst_handle_sal(CPUS390XState *env, uint64_t reg1); void ioinst_handle_sal(S390CPU *cpu, uint64_t reg1);
#endif #endif
...@@ -446,8 +446,6 @@ static int kvm_sclp_service_call(S390CPU *cpu, struct kvm_run *run, ...@@ -446,8 +446,6 @@ static int kvm_sclp_service_call(S390CPU *cpu, struct kvm_run *run,
static int kvm_handle_css_inst(S390CPU *cpu, struct kvm_run *run, static int kvm_handle_css_inst(S390CPU *cpu, struct kvm_run *run,
uint8_t ipa0, uint8_t ipa1, uint8_t ipb) uint8_t ipa0, uint8_t ipa1, uint8_t ipb)
{ {
int r = 0;
int no_cc = 0;
CPUS390XState *env = &cpu->env; CPUS390XState *env = &cpu->env;
CPUState *cs = CPU(cpu); CPUState *cs = CPU(cpu);
...@@ -461,69 +459,61 @@ static int kvm_handle_css_inst(S390CPU *cpu, struct kvm_run *run, ...@@ -461,69 +459,61 @@ static int kvm_handle_css_inst(S390CPU *cpu, struct kvm_run *run,
switch (ipa1) { switch (ipa1) {
case PRIV_XSCH: case PRIV_XSCH:
r = ioinst_handle_xsch(env, env->regs[1]); ioinst_handle_xsch(cpu, env->regs[1]);
break; break;
case PRIV_CSCH: case PRIV_CSCH:
r = ioinst_handle_csch(env, env->regs[1]); ioinst_handle_csch(cpu, env->regs[1]);
break; break;
case PRIV_HSCH: case PRIV_HSCH:
r = ioinst_handle_hsch(env, env->regs[1]); ioinst_handle_hsch(cpu, env->regs[1]);
break; break;
case PRIV_MSCH: case PRIV_MSCH:
r = ioinst_handle_msch(env, env->regs[1], run->s390_sieic.ipb); ioinst_handle_msch(cpu, env->regs[1], run->s390_sieic.ipb);
break; break;
case PRIV_SSCH: case PRIV_SSCH:
r = ioinst_handle_ssch(env, env->regs[1], run->s390_sieic.ipb); ioinst_handle_ssch(cpu, env->regs[1], run->s390_sieic.ipb);
break; break;
case PRIV_STCRW: case PRIV_STCRW:
r = ioinst_handle_stcrw(env, run->s390_sieic.ipb); ioinst_handle_stcrw(cpu, run->s390_sieic.ipb);
break; break;
case PRIV_STSCH: case PRIV_STSCH:
r = ioinst_handle_stsch(env, env->regs[1], run->s390_sieic.ipb); ioinst_handle_stsch(cpu, env->regs[1], run->s390_sieic.ipb);
break; break;
case PRIV_TSCH: case PRIV_TSCH:
/* We should only get tsch via KVM_EXIT_S390_TSCH. */ /* We should only get tsch via KVM_EXIT_S390_TSCH. */
fprintf(stderr, "Spurious tsch intercept\n"); fprintf(stderr, "Spurious tsch intercept\n");
break; break;
case PRIV_CHSC: case PRIV_CHSC:
r = ioinst_handle_chsc(env, run->s390_sieic.ipb); ioinst_handle_chsc(cpu, run->s390_sieic.ipb);
break; break;
case PRIV_TPI: case PRIV_TPI:
/* This should have been handled by kvm already. */ /* This should have been handled by kvm already. */
fprintf(stderr, "Spurious tpi intercept\n"); fprintf(stderr, "Spurious tpi intercept\n");
break; break;
case PRIV_SCHM: case PRIV_SCHM:
no_cc = 1; ioinst_handle_schm(cpu, env->regs[1], env->regs[2],
r = ioinst_handle_schm(env, env->regs[1], env->regs[2], run->s390_sieic.ipb);
run->s390_sieic.ipb);
break; break;
case PRIV_RSCH: case PRIV_RSCH:
r = ioinst_handle_rsch(env, env->regs[1]); ioinst_handle_rsch(cpu, env->regs[1]);
break; break;
case PRIV_RCHP: case PRIV_RCHP:
r = ioinst_handle_rchp(env, env->regs[1]); ioinst_handle_rchp(cpu, env->regs[1]);
break; break;
case PRIV_STCPS: case PRIV_STCPS:
/* We do not provide this instruction, it is suppressed. */ /* We do not provide this instruction, it is suppressed. */
no_cc = 1;
r = 0;
break; break;
case PRIV_SAL: case PRIV_SAL:
no_cc = 1; ioinst_handle_sal(cpu, env->regs[1]);
r = ioinst_handle_sal(env, env->regs[1]);
break; break;
case PRIV_SIGA: case PRIV_SIGA:
/* Not provided, set CC = 3 for subchannel not operational */ /* Not provided, set CC = 3 for subchannel not operational */
r = 3; setcc(cpu, 3);
break; break;
default: default:
return -1; return -1;
} }
if (r >= 0 && !no_cc) {
setcc(cpu, r);
}
return 0; return 0;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册