void kvm_s390_vcpu_interrupt(S390CPU *cpu, 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);
+void kvm_s390_access_exception(S390CPU *cpu, uint16_t code, uint64_t te_code);
#else
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_access_exception(S390CPU *cpu, uint16_t code,
+ uint64_t te_code)
+{
+}
#endif
S390CPU *s390_cpu_addr2state(uint16_t cpu_addr);
unsigned int s390_cpu_halt(S390CPU *cpu);
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,
uint16_t ipbh0)
{
#define FS_READ 0x800
#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,
uint64_t asc, int rw, bool exc)
{
- CPUState *cs = CPU(s390_env_get_cpu(env));
uint64_t tec;
tec = vaddr | (rw == 1 ? FS_WRITE : FS_READ) | 4 | asc >> 46;
return;
}
- stq_phys(cs->as, env->psa + offsetof(LowCore, trans_exc_code), tec);
- trigger_pgm_exception(env, PGM_PROTECTION, ILEN_LATER_INC);
+ trigger_access_exception(env, PGM_PROTECTION, ILEN_LATER_INC, tec);
}
static void trigger_page_fault(CPUS390XState *env, target_ulong vaddr,
uint32_t type, uint64_t asc, int rw, bool exc)
{
- CPUState *cs = CPU(s390_env_get_cpu(env));
int ilen = ILEN_LATER;
uint64_t tec;
ilen = 2;
}
- stq_phys(cs->as, env->psa + offsetof(LowCore, trans_exc_code), tec);
- trigger_pgm_exception(env, type, ilen);
+ trigger_access_exception(env, type, ilen, tec);
}
/**