s390x/kvm: Support access register mode for KVM_S390_MEM_OP ioctl

Access register mode is one of the modes that control dynamic address
translation. In this mode the address space is specified by values of
the access registers. The effective address-space-control element is
obtained from the result of the access register translation. See
the "Access-Register Introduction" section of the chapter 5 "Program
Execution" in "Principles of Operations" for more details.

When the CPU is in AR mode, the s390_cpu_virt_mem_rw() function must
know which access register number to use for address translation.
This patch does several things:
- add new parameter 'uint8_t ar' to that function
- decode ar number from intercepted instructions
- pass the ar number to s390_cpu_virt_mem_rw(), which in turn passes it
to the KVM_S390_MEM_OP ioctl.

Signed-off-by: Alexander Yarygin <yarygin@linux.vnet.ibm.com>
Reviewed-by: Thomas Huth <thuth@linux.vnet.ibm.com>
Reviewed-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
This commit is contained in:
Alexander Yarygin 2015-03-05 12:36:48 +03:00 committed by Cornelia Huck
parent a9bcd1b871
commit 6cb1e49de5
6 changed files with 90 additions and 61 deletions

View file

@ -155,7 +155,7 @@ int clp_service_call(S390CPU *cpu, uint8_t r2)
return 0;
}
if (s390_cpu_virt_mem_read(cpu, env->regs[r2], buffer, sizeof(*reqh))) {
if (s390_cpu_virt_mem_read(cpu, env->regs[r2], r2, buffer, sizeof(*reqh))) {
return 0;
}
reqh = (ClpReqHdr *)buffer;
@ -165,7 +165,7 @@ int clp_service_call(S390CPU *cpu, uint8_t r2)
return 0;
}
if (s390_cpu_virt_mem_read(cpu, env->regs[r2], buffer,
if (s390_cpu_virt_mem_read(cpu, env->regs[r2], r2, buffer,
req_len + sizeof(*resh))) {
return 0;
}
@ -180,7 +180,7 @@ int clp_service_call(S390CPU *cpu, uint8_t r2)
return 0;
}
if (s390_cpu_virt_mem_read(cpu, env->regs[r2], buffer,
if (s390_cpu_virt_mem_read(cpu, env->regs[r2], r2, buffer,
req_len + res_len)) {
return 0;
}
@ -277,7 +277,7 @@ int clp_service_call(S390CPU *cpu, uint8_t r2)
}
out:
if (s390_cpu_virt_mem_write(cpu, env->regs[r2], buffer,
if (s390_cpu_virt_mem_write(cpu, env->regs[r2], r2, buffer,
req_len + res_len)) {
return 0;
}
@ -546,7 +546,8 @@ out:
return 0;
}
int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t gaddr)
int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t gaddr,
uint8_t ar)
{
CPUS390XState *env = &cpu->env;
S390PCIBusDevice *pbdev;
@ -603,7 +604,7 @@ int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t gaddr)
return 0;
}
if (s390_cpu_virt_mem_read(cpu, gaddr, buffer, len)) {
if (s390_cpu_virt_mem_read(cpu, gaddr, ar, buffer, len)) {
return 0;
}
@ -698,7 +699,7 @@ static void dereg_ioat(S390PCIBusDevice *pbdev)
pbdev->g_iota = 0;
}
int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba)
int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar)
{
CPUS390XState *env = &cpu->env;
uint8_t oc;
@ -727,7 +728,7 @@ int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba)
return 0;
}
if (s390_cpu_virt_mem_read(cpu, fiba, (uint8_t *)&fib, sizeof(fib))) {
if (s390_cpu_virt_mem_read(cpu, fiba, ar, (uint8_t *)&fib, sizeof(fib))) {
return 0;
}
@ -773,7 +774,7 @@ int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba)
return 0;
}
int stpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba)
int stpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar)
{
CPUS390XState *env = &cpu->env;
uint32_t fh;
@ -829,7 +830,7 @@ int stpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba)
fib.fc |= 0x10;
}
if (s390_cpu_virt_mem_write(cpu, fiba, (uint8_t *)&fib, sizeof(fib))) {
if (s390_cpu_virt_mem_write(cpu, fiba, ar, (uint8_t *)&fib, sizeof(fib))) {
return 0;
}

View file

@ -281,8 +281,9 @@ int clp_service_call(S390CPU *cpu, uint8_t r2);
int pcilg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2);
int pcistg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2);
int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2);
int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t gaddr);
int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba);
int stpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba);
int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t gaddr,
uint8_t ar);
int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar);
int stpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar);
#endif