mirror of https://github.com/xemu-project/xemu.git
s390x: Add SIDA memory ops
Protected guests save the instruction control blocks in the SIDA instead of QEMU/KVM directly accessing the guest's memory. Let's introduce new functions to access the SIDA. The memops for doing so are available with KVM_CAP_S390_PROTECTED, so let's check for that. Signed-off-by: Janosch Frank <frankja@linux.ibm.com> Reviewed-by: David Hildenbrand <david@redhat.com> Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com> Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com> Reviewed-by: Cornelia Huck <cohuck@redhat.com> Message-Id: <20200319131921.2367-8-frankja@linux.ibm.com> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
This commit is contained in:
parent
2585e507ff
commit
1cca826549
|
@ -823,7 +823,12 @@ int s390_cpu_virt_mem_rw(S390CPU *cpu, vaddr laddr, uint8_t ar, void *hostbuf,
|
||||||
#define s390_cpu_virt_mem_check_write(cpu, laddr, ar, len) \
|
#define s390_cpu_virt_mem_check_write(cpu, laddr, ar, len) \
|
||||||
s390_cpu_virt_mem_rw(cpu, laddr, ar, NULL, len, true)
|
s390_cpu_virt_mem_rw(cpu, laddr, ar, NULL, len, true)
|
||||||
void s390_cpu_virt_mem_handle_exc(S390CPU *cpu, uintptr_t ra);
|
void s390_cpu_virt_mem_handle_exc(S390CPU *cpu, uintptr_t ra);
|
||||||
|
int s390_cpu_pv_mem_rw(S390CPU *cpu, unsigned int offset, void *hostbuf,
|
||||||
|
int len, bool is_write);
|
||||||
|
#define s390_cpu_pv_mem_read(cpu, offset, dest, len) \
|
||||||
|
s390_cpu_pv_mem_rw(cpu, offset, dest, len, false)
|
||||||
|
#define s390_cpu_pv_mem_write(cpu, offset, dest, len) \
|
||||||
|
s390_cpu_pv_mem_rw(cpu, offset, dest, len, true)
|
||||||
|
|
||||||
/* sigp.c */
|
/* sigp.c */
|
||||||
int s390_cpu_restart(S390CPU *cpu);
|
int s390_cpu_restart(S390CPU *cpu);
|
||||||
|
|
|
@ -154,6 +154,7 @@ static int cap_ri;
|
||||||
static int cap_gs;
|
static int cap_gs;
|
||||||
static int cap_hpage_1m;
|
static int cap_hpage_1m;
|
||||||
static int cap_vcpu_resets;
|
static int cap_vcpu_resets;
|
||||||
|
static int cap_protected;
|
||||||
|
|
||||||
static int active_cmma;
|
static int active_cmma;
|
||||||
|
|
||||||
|
@ -351,6 +352,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
|
||||||
cap_mem_op = kvm_check_extension(s, KVM_CAP_S390_MEM_OP);
|
cap_mem_op = kvm_check_extension(s, KVM_CAP_S390_MEM_OP);
|
||||||
cap_s390_irq = kvm_check_extension(s, KVM_CAP_S390_INJECT_IRQ);
|
cap_s390_irq = kvm_check_extension(s, KVM_CAP_S390_INJECT_IRQ);
|
||||||
cap_vcpu_resets = kvm_check_extension(s, KVM_CAP_S390_VCPU_RESETS);
|
cap_vcpu_resets = kvm_check_extension(s, KVM_CAP_S390_VCPU_RESETS);
|
||||||
|
cap_protected = kvm_check_extension(s, KVM_CAP_S390_PROTECTED);
|
||||||
|
|
||||||
if (!kvm_check_extension(s, KVM_CAP_S390_GMAP)
|
if (!kvm_check_extension(s, KVM_CAP_S390_GMAP)
|
||||||
|| !kvm_check_extension(s, KVM_CAP_S390_COW)) {
|
|| !kvm_check_extension(s, KVM_CAP_S390_COW)) {
|
||||||
|
@ -851,6 +853,30 @@ int kvm_s390_mem_op(S390CPU *cpu, vaddr addr, uint8_t ar, void *hostbuf,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int kvm_s390_mem_op_pv(S390CPU *cpu, uint64_t offset, void *hostbuf,
|
||||||
|
int len, bool is_write)
|
||||||
|
{
|
||||||
|
struct kvm_s390_mem_op mem_op = {
|
||||||
|
.sida_offset = offset,
|
||||||
|
.size = len,
|
||||||
|
.op = is_write ? KVM_S390_MEMOP_SIDA_WRITE
|
||||||
|
: KVM_S390_MEMOP_SIDA_READ,
|
||||||
|
.buf = (uint64_t)hostbuf,
|
||||||
|
};
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!cap_mem_op || !cap_protected) {
|
||||||
|
return -ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = kvm_vcpu_ioctl(CPU(cpu), KVM_S390_MEM_OP, &mem_op);
|
||||||
|
if (ret < 0) {
|
||||||
|
error_report("KVM_S390_MEM_OP failed: %s", strerror(-ret));
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Legacy layout for s390:
|
* Legacy layout for s390:
|
||||||
* Older S390 KVM requires the topmost vma of the RAM to be
|
* Older S390 KVM requires the topmost vma of the RAM to be
|
||||||
|
|
|
@ -19,6 +19,8 @@ void kvm_s390_vcpu_interrupt(S390CPU *cpu, struct kvm_s390_irq *irq);
|
||||||
void kvm_s390_access_exception(S390CPU *cpu, uint16_t code, uint64_t te_code);
|
void kvm_s390_access_exception(S390CPU *cpu, uint16_t code, uint64_t te_code);
|
||||||
int kvm_s390_mem_op(S390CPU *cpu, vaddr addr, uint8_t ar, void *hostbuf,
|
int kvm_s390_mem_op(S390CPU *cpu, vaddr addr, uint8_t ar, void *hostbuf,
|
||||||
int len, bool is_write);
|
int len, bool is_write);
|
||||||
|
int kvm_s390_mem_op_pv(S390CPU *cpu, vaddr addr, void *hostbuf, int len,
|
||||||
|
bool is_write);
|
||||||
void kvm_s390_program_interrupt(S390CPU *cpu, uint16_t code);
|
void kvm_s390_program_interrupt(S390CPU *cpu, uint16_t code);
|
||||||
int kvm_s390_set_cpu_state(S390CPU *cpu, uint8_t cpu_state);
|
int kvm_s390_set_cpu_state(S390CPU *cpu, uint8_t cpu_state);
|
||||||
void kvm_s390_vcpu_interrupt_pre_save(S390CPU *cpu);
|
void kvm_s390_vcpu_interrupt_pre_save(S390CPU *cpu);
|
||||||
|
|
|
@ -474,6 +474,20 @@ static int translate_pages(S390CPU *cpu, vaddr addr, int nr_pages,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int s390_cpu_pv_mem_rw(S390CPU *cpu, unsigned int offset, void *hostbuf,
|
||||||
|
int len, bool is_write)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (kvm_enabled()) {
|
||||||
|
ret = kvm_s390_mem_op_pv(cpu, offset, hostbuf, len, is_write);
|
||||||
|
} else {
|
||||||
|
/* Protected Virtualization is a KVM/Hardware only feature */
|
||||||
|
g_assert_not_reached();
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* s390_cpu_virt_mem_rw:
|
* s390_cpu_virt_mem_rw:
|
||||||
* @laddr: the logical start address
|
* @laddr: the logical start address
|
||||||
|
|
Loading…
Reference in New Issue