mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-09 10:34:58 -06:00
s390x/kvm: Add function for injecting pgm access exceptions
Program access exceptions are defined to deliver a translation exception code in the low-core. Add a function trigger_access_exception() that generates the proper program interrupt on both KVM and non-KVM systems and switch the existing code to use it. Signed-off-by: Thomas Huth <thuth@linux.vnet.ibm.com> Signed-off-by: Jens Freimann <jfrei@linux.vnet.ibm.com> Reviewed-by: David Hildenbrand <dahi@linux.vnet.ibm.com> Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
This commit is contained in:
parent
9d77309c9f
commit
801cdd355f
3 changed files with 33 additions and 6 deletions
|
@ -397,6 +397,7 @@ void kvm_s390_service_interrupt(uint32_t parm);
|
||||||
void kvm_s390_vcpu_interrupt(S390CPU *cpu, struct kvm_s390_irq *irq);
|
void kvm_s390_vcpu_interrupt(S390CPU *cpu, struct kvm_s390_irq *irq);
|
||||||
void kvm_s390_floating_interrupt(struct kvm_s390_irq *irq);
|
void kvm_s390_floating_interrupt(struct kvm_s390_irq *irq);
|
||||||
int kvm_s390_inject_flic(struct kvm_s390_irq *irq);
|
int kvm_s390_inject_flic(struct kvm_s390_irq *irq);
|
||||||
|
void kvm_s390_access_exception(S390CPU *cpu, uint16_t code, uint64_t te_code);
|
||||||
#else
|
#else
|
||||||
static inline void kvm_s390_virtio_irq(int config_change, uint64_t token)
|
static inline void kvm_s390_virtio_irq(int config_change, uint64_t token)
|
||||||
{
|
{
|
||||||
|
@ -404,6 +405,10 @@ static inline void kvm_s390_virtio_irq(int config_change, uint64_t token)
|
||||||
static inline void kvm_s390_service_interrupt(uint32_t parm)
|
static inline void kvm_s390_service_interrupt(uint32_t parm)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
static inline void kvm_s390_access_exception(S390CPU *cpu, uint16_t code,
|
||||||
|
uint64_t te_code)
|
||||||
|
{
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
S390CPU *s390_cpu_addr2state(uint16_t cpu_addr);
|
S390CPU *s390_cpu_addr2state(uint16_t cpu_addr);
|
||||||
unsigned int s390_cpu_halt(S390CPU *cpu);
|
unsigned int s390_cpu_halt(S390CPU *cpu);
|
||||||
|
|
|
@ -757,6 +757,18 @@ static void enter_pgmcheck(S390CPU *cpu, uint16_t code)
|
||||||
kvm_s390_vcpu_interrupt(cpu, &irq);
|
kvm_s390_vcpu_interrupt(cpu, &irq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void kvm_s390_access_exception(S390CPU *cpu, uint16_t code, uint64_t te_code)
|
||||||
|
{
|
||||||
|
struct kvm_s390_irq irq = {
|
||||||
|
.type = KVM_S390_PROGRAM_INT,
|
||||||
|
.u.pgm.code = code,
|
||||||
|
.u.pgm.trans_exc_code = te_code,
|
||||||
|
.u.pgm.exc_access_id = te_code & 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
kvm_s390_vcpu_interrupt(cpu, &irq);
|
||||||
|
}
|
||||||
|
|
||||||
static int kvm_sclp_service_call(S390CPU *cpu, struct kvm_run *run,
|
static int kvm_sclp_service_call(S390CPU *cpu, struct kvm_run *run,
|
||||||
uint16_t ipbh0)
|
uint16_t ipbh0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -46,10 +46,23 @@
|
||||||
#define FS_READ 0x800
|
#define FS_READ 0x800
|
||||||
#define FS_WRITE 0x400
|
#define FS_WRITE 0x400
|
||||||
|
|
||||||
|
static void trigger_access_exception(CPUS390XState *env, uint32_t type,
|
||||||
|
uint32_t ilen, uint64_t tec)
|
||||||
|
{
|
||||||
|
S390CPU *cpu = s390_env_get_cpu(env);
|
||||||
|
|
||||||
|
if (kvm_enabled()) {
|
||||||
|
kvm_s390_access_exception(cpu, type, tec);
|
||||||
|
} else {
|
||||||
|
CPUState *cs = CPU(cpu);
|
||||||
|
stq_phys(cs->as, env->psa + offsetof(LowCore, trans_exc_code), tec);
|
||||||
|
trigger_pgm_exception(env, type, ilen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void trigger_prot_fault(CPUS390XState *env, target_ulong vaddr,
|
static void trigger_prot_fault(CPUS390XState *env, target_ulong vaddr,
|
||||||
uint64_t asc, int rw, bool exc)
|
uint64_t asc, int rw, bool exc)
|
||||||
{
|
{
|
||||||
CPUState *cs = CPU(s390_env_get_cpu(env));
|
|
||||||
uint64_t tec;
|
uint64_t tec;
|
||||||
|
|
||||||
tec = vaddr | (rw == 1 ? FS_WRITE : FS_READ) | 4 | asc >> 46;
|
tec = vaddr | (rw == 1 ? FS_WRITE : FS_READ) | 4 | asc >> 46;
|
||||||
|
@ -60,14 +73,12 @@ static void trigger_prot_fault(CPUS390XState *env, target_ulong vaddr,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
stq_phys(cs->as, env->psa + offsetof(LowCore, trans_exc_code), tec);
|
trigger_access_exception(env, PGM_PROTECTION, ILEN_LATER_INC, tec);
|
||||||
trigger_pgm_exception(env, PGM_PROTECTION, ILEN_LATER_INC);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void trigger_page_fault(CPUS390XState *env, target_ulong vaddr,
|
static void trigger_page_fault(CPUS390XState *env, target_ulong vaddr,
|
||||||
uint32_t type, uint64_t asc, int rw, bool exc)
|
uint32_t type, uint64_t asc, int rw, bool exc)
|
||||||
{
|
{
|
||||||
CPUState *cs = CPU(s390_env_get_cpu(env));
|
|
||||||
int ilen = ILEN_LATER;
|
int ilen = ILEN_LATER;
|
||||||
uint64_t tec;
|
uint64_t tec;
|
||||||
|
|
||||||
|
@ -84,8 +95,7 @@ static void trigger_page_fault(CPUS390XState *env, target_ulong vaddr,
|
||||||
ilen = 2;
|
ilen = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
stq_phys(cs->as, env->psa + offsetof(LowCore, trans_exc_code), tec);
|
trigger_access_exception(env, type, ilen, tec);
|
||||||
trigger_pgm_exception(env, type, ilen);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue