s390x: flic rework, tcg flic support and STSI
v2 cover s390x: flic rework, tcg flic support and STSI
This patch series implements floating interrupt support for TCG and fixes STSI so we can remove warnings related to s390x SMP and MTTCG.
KVM code has to be touched in order to factor out the injection routines into the flic ("s390x/flic: factor out injection of floating interrupts"). Basic testing didn't reveal any problems so far.
With this series I am now able to run fedora 26/27 and Ubuntu 17.10+ with 16 VCPUs (MTTCG) on a 8CPU host, doing a make -j16 in the guest. I got nasty stalls in the guest beforehand.
Now also included: More flic related caching to avoid recurring conversions.
Based on: https://github.com/cohuck/qemu.git s390x-next Available at: https://github.com/davidhildenbrand/qemu.git s390x-queue
v1 -> v2:
- Added due to discussions:
- "s390x/flic: no need to call s390_io_interrupt() from flic"
- "s390x/tcg: cache the qemu flic in a central function"
- "s390x/kvm: cache the kvm flic in a central function"
- "s390x/flic: cache the common flic class in a central function"
- "s390x/flic: simplify flic initialization"
- no need to check for tcg_enabled()
- "s390x/tcg: STSI overhaul"
- rephrased the comment
- "s390x/tcg: implement TEST PENDING INTERRUPTION"
- renamed local variable
- "s390x: fix size + content of STSI blocks"
- added typedefs whiel touching it. Thomas, therefore not added your r-b.
- Minor spelling errors fixed
- Dropped a couple of unneeded OBJECT() conversion
David Hildenbrand (18):
s390x/tcg: deliver multiple interrupts in a row s390x/flic: simplify flic initialization
s390x/tcg: simplify lookup of flic
s390x/tcg: simplify machine check handling s390x/flic: factor out injection of floating interrupts s390x/flic: no need to call s390_io_interrupt() from flic s390x/tcg: tolerate wrong wakeups due to floating interrupts s390x/flic: make floating interrupts on TCG actually floating s390x/tcg: implement TEST PENDING INTERRUPTION s390x/flic: implement qemu_s390_clear_io_flic() s390x/flic: optimize CPU wakeup for TCG
s390x: fix size + content of STSI blocks
s390x/tcg: STSI overhaul
s390x/tcg: remove SMP warning
configure: s390x supports mttcg now
s390x/tcg: cache the qemu flic in a central function s390x/kvm: cache the kvm flic in a central function s390x/flic: cache the common flic class in a central function
configure | 1 + hw/intc/s390_flic.c | 257 +++++++++++++++++++++++++++++++++++++++-- hw/intc/s390_flic_kvm.c | 84 +++++++++++--- hw/s390x/css.c | 10 +- hw/s390x/s390-virtio-ccw.c | 4 - hw/s390x/virtio-ccw.c | 4 +- include/hw/s390x/s390_flic.h | 57 ++++++++-- target/s390x/cpu.c | 10 -- target/s390x/cpu.h | 99 ++++++++-------- target/s390x/excp_helper.c | 147 +++++++++--------------- target/s390x/helper.h | 1 + target/s390x/insn-data.def | 1 + target/s390x/internal.h | 5 - target/s390x/interrupt.c | 100 ++++------------ target/s390x/kvm-stub.c | 13 --- target/s390x/kvm.c | 70 +----------- target/s390x/kvm_s390x.h | 10 +- target/s390x/misc_helper.c | 266 +++++++++++++++++++++++++++---------------- target/s390x/translate.c | 8 ++ 19 files changed, 680 insertions(+), 467 deletions(-)
Signature · 1 line
2.14.3
PATCH v2 1/18 s390x/tcg: deliver multiple interrupts in a row
We have to consider all deliverable interrupts.
We now have to take care of the special scenario, where we first inject an interrupt with a WAIT PSW, followed by a !WAIT PSW. (very unlikely but possible)
--- target/s390x/excp_helper.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-)
target/s390x/excp_helper.c +16 -4
@@ -433,10 +433,12 @@ void s390_cpu_do_interrupt(CPUState *cs) {S390CPU *cpu =S390_CPU (cs);CPUS390XState *env = &cpu->env; +bool stopped = false;qemu_log_mask (CPU_LOG_INT ,"%s: %d at pc=%" PRIx64"\n" , __func__, cs->exception_index, env->psw.addr); +try_deliver:/* handle machine checks */ if (cs->exception_index ==-1 &&s390_cpu_has_mcck_int (cpu)) { cs->exception_index =EXCP_MCHK ;
@@ -479,13 +481,14 @@ void s390_cpu_do_interrupt(CPUState *cs)break ;case EXCP_STOP :do_stop_interrupt (env); + stopped = true;break ; } -/* WAIT PSW during interrupt injection or STOP interrupt */ -if (cs->exception_index ==EXCP_HLT ) { -/* don't trigger a cpu_loop_exit(), use an interrupt instead */ -cpu_interrupt (CPU (cpu),CPU_INTERRUPT_HALT ); +if (cs->exception_index !=-1 && !stopped) { +/* check if there are more pending interrupts to deliver */ + cs->exception_index =-1 ; + goto try_deliver; } cs->exception_index =-1 ;
@@ -493,6 +496,15 @@ void s390_cpu_do_interrupt(CPUState *cs)if (!env->pending_int) { cs->interrupt_request &= ~CPU_INTERRUPT_HARD ; } + +/* WAIT PSW during interrupt injection or STOP interrupt */ +if ((env->psw.mask &PSW_MASK_WAIT ) || stopped) { +/* don't trigger a cpu_loop_exit(), use an interrupt instead */ +cpu_interrupt (CPU (cpu),CPU_INTERRUPT_HALT ); + }else if (cs->halted) { +/* unhalt if we had a WAIT PSW somehwere in our injection chain */ +s390_cpu_unhalt (cpu); + } }bool s390_cpu_exec_interrupt (CPUState *cs,int interrupt_request)
Signature · 1 line
2.14.3
PATCH v2 2/18 s390x/flic: simplify flic initialization
In reply to David HildenbrandThis makes it clearer, which device is used for which accelerator.
--- hw/intc/s390_flic.c | 7 +++++-- hw/intc/s390_flic_kvm.c | 12 ------------ include/hw/s390x/s390_flic.h | 9 --------- 3 files changed, 5 insertions(+), 23 deletions(-)
hw/intc/s390_flic.c +5 -2
@@ -40,8 +40,11 @@ void s390_flic_init(void) {DeviceState *dev; - dev =s390_flic_kvm_create (); -if (!dev) { +if (kvm_enabled ()) { + dev =qdev_create (NULL ,TYPE_KVM_S390_FLIC ); +object_property_add_child (qdev_get_machine (),TYPE_KVM_S390_FLIC , +OBJECT (dev),NULL ); + }else { dev =qdev_create (NULL ,TYPE_QEMU_S390_FLIC );object_property_add_child (qdev_get_machine (),TYPE_QEMU_S390_FLIC ,OBJECT (dev),NULL );
hw/intc/s390_flic_kvm.c +0 -12
@@ -35,18 +35,6 @@ typedef struct KVMS390FLICState {bool clear_io_supported; } KVMS390FLICState; -DeviceState *s390_flic_kvm_create (void ) -{ -DeviceState *dev =NULL ; - -if (kvm_enabled ()) { - dev =qdev_create (NULL ,TYPE_KVM_S390_FLIC ); -object_property_add_child (qdev_get_machine (),TYPE_KVM_S390_FLIC , -OBJECT (dev),NULL ); - } -return dev; -} -/** * flic_get_all_irqs - store all pending irqs in buffer * @buf: pointer to buffer which is passed to kernel
include/hw/s390x/s390_flic.h +0 -9
@@ -91,13 +91,4 @@ void s390_flic_init(void);S390FLICState *s390_get_flic (void );bool ais_needed (void *opaque); -#ifdef CONFIG_KVM -DeviceState *s390_flic_kvm_create (void ); -#else -static inline DeviceState *s390_flic_kvm_create (void ) -{ -return NULL ; -} -#endif -#endif /* HW_S390_FLIC_H */
Signature · 1 line
2.14.3
PATCH v2 3/18 s390x/tcg: simplify lookup of flic
In reply to David HildenbrandWe can simply search for an object of our common type.
--- hw/intc/s390_flic.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)
hw/intc/s390_flic.c +3 -5
@@ -27,11 +27,9 @@ S390FLICState *s390_get_flic(void)static S390FLICState *fs;if (!fs) { - fs =S390_FLIC_COMMON (object_resolve_path (TYPE_KVM_S390_FLIC ,NULL )); -if (!fs) { - fs =S390_FLIC_COMMON (object_resolve_path (TYPE_QEMU_S390_FLIC , -NULL )); - } + fs =S390_FLIC_COMMON (object_resolve_path_type ("" , +TYPE_S390_FLIC_COMMON , +NULL )); }return fs; }
Signature · 1 line
2.14.3
PATCH v2 4/18 s390x/tcg: simplify machine check handling
In reply to David HildenbrandWe currently only support CRW machine checks. This is a preparation for real floating interrupt support.
Get rid of the queue and handle it via the bit INTERRUPT_MCHK. We don't rename it for now, as it will be soon gone (when moving crw machine checks into the flic).
Please note that this is the same way also KVM handles it: only one instance of a machine check can be pending at a time. So no need for a queue.
While at it, make sure we try to deliver only if env->cregs[14] actually indicates that CRWs are accepted.
Drop two unused defines on the way (we already have PSW_MASK_...).
--- target/s390x/cpu.c | 2 -- target/s390x/cpu.h | 10 ---------- target/s390x/excp_helper.c | 29 +++++------------------------ target/s390x/interrupt.c | 18 +++++++----------- 4 files changed, 12 insertions(+), 47 deletions(-)
target/s390x/cpu.c +0 -2
@@ -118,7 +118,6 @@ static void s390_cpu_initial_reset(CPUState *s)for (i =0 ; i <ARRAY_SIZE (env->io_index); i++) { env->io_index[i] =-1 ; } - env->mchk_index =-1 ;/* tininess for underflow is detected before rounding */ set_float_detect_tininess(float_tininess_before_rounding,
@@ -155,7 +154,6 @@ static void s390_cpu_full_reset(CPUState *s)for (i =0 ; i <ARRAY_SIZE (env->io_index); i++) { env->io_index[i] =-1 ; } - env->mchk_index =-1 ;/* tininess for underflow is detected before rounding */ set_float_detect_tininess(float_tininess_before_rounding,
target/s390x/cpu.h +0 -10
@@ -54,10 +54,6 @@#define MMU_USER_IDX 0#define MAX_IO_QUEUE 16 -#define MAX_MCHK_QUEUE 16 - -#define PSW_MCHK_MASK 0x0004000000000000 -#define PSW_IO_MASK 0x0200000000000000#define S390_MAX_CPUS 248
@@ -73,10 +69,6 @@ typedef struct IOIntQueue {uint32_t word; } IOIntQueue; -typedef struct MchkQueue { -uint16_t type; -}MchkQueue ; -struct CPUS390XState {uint64_t regs[16 ];/* GP registers */ /*
@@ -122,14 +114,12 @@ struct CPUS390XState {uint64_t cregs[16 ];/* control registers */ IOIntQueue io_queue[MAX_IO_QUEUE ][8 ]; -MchkQueue mchk_queue[MAX_MCHK_QUEUE ];int pending_int;uint32_t service_param;uint16_t external_call_addr;DECLARE_BITMAP (emergency_signals,S390_MAX_CPUS );int io_index[8 ]; -int mchk_index;uint64_t ckc;uint64_t cputm;
target/s390x/excp_helper.c +5 -24
@@ -368,30 +368,16 @@ static void do_io_interrupt(CPUS390XState *env)static void do_mchk_interrupt (CPUS390XState *env) { -S390CPU *cpu =s390_env_get_cpu (env);uint64_t mask, addr;LowCore *lowcore; -MchkQueue *q;int i; -if (!(env->psw.mask &PSW_MASK_MCHECK )) { -cpu_abort (CPU (cpu),"Machine check w/o mchk mask\n" ); - } +/* for now we only support channel report machine checks (floating) */ +g_assert (env->psw.mask &PSW_MASK_MCHECK ); +g_assert (env->cregs[14 ] &CR0_SERVICE_SC ); -if (env->mchk_index <0 || env->mchk_index >=MAX_MCHK_QUEUE ) { -cpu_abort (CPU (cpu),"Mchk queue overrun: %d\n" , env->mchk_index); - } - - q = &env->mchk_queue[env->mchk_index]; - -if (q->type !=1 ) { -/* Don't know how to handle this... */ -cpu_abort (CPU (cpu),"Unknown machine check type %d\n" , q->type); - } -if (!(env->cregs[14 ] & (1 <<28 ))) { -/* CRW machine checks disabled */ -return ; - } +g_assert (env->pending_int &INTERRUPT_MCHK ); + env->pending_int &= ~INTERRUPT_MCHK ; lowcore =cpu_map_lowcore (env);
@@ -418,11 +404,6 @@ static void do_mchk_interrupt(CPUS390XState *env)cpu_unmap_lowcore (lowcore); - env->mchk_index--; -if (env->mchk_index ==-1 ) { - env->pending_int &= ~INTERRUPT_MCHK ; - } -DPRINTF ("%s: %" PRIx64" %" PRIx64"\n" , __func__, env->psw.mask, env->psw.addr);
target/s390x/interrupt.c +7 -11
@@ -162,16 +162,6 @@ static void cpu_inject_crw_mchk(S390CPU *cpu) {CPUS390XState *env = &cpu->env; -if (env->mchk_index ==MAX_MCHK_QUEUE -1 ) { -/* ugh - can't queue anymore. Let's drop. */ -return ; - } - - env->mchk_index++; -assert (env->mchk_index <MAX_MCHK_QUEUE ); - - env->mchk_queue[env->mchk_index].type =1 ; - env->pending_int |=INTERRUPT_MCHK ;cpu_interrupt (CPU (cpu),CPU_INTERRUPT_HARD ); }
@@ -225,7 +215,13 @@ bool s390_cpu_has_mcck_int(S390CPU *cpu)return false; } -return env->pending_int &INTERRUPT_MCHK ; +/* for now we only support channel report machine checks (floating) */ +if ((env->pending_int &INTERRUPT_MCHK ) && + (env->cregs[14 ] &CR14_CHANNEL_REPORT_SC )) { +return true; + } + +return false; }bool s390_cpu_has_ext_int (S390CPU *cpu)
Signature · 1 line
2.14.3
PATCH v2 5/18 s390x/flic: factor out injection of floating interrupts
In reply to David HildenbrandLet the flic device handle it internally. This will allow us to later on store floating interrupts in the flic for the TCG case.
This now also simplifies kvm.c. All that's left is the fallback interface for floating interrupts, which is now triggered directly via the flic in case anything goes wrong.
--- hw/intc/s390_flic.c | 31 ++++++++++++++++++++ hw/intc/s390_flic_kvm.c | 63 ++++++++++++++++++++++++++++++++++++---- include/hw/s390x/s390_flic.h | 5 ++++ target/s390x/cpu.h | 7 ++++- target/s390x/interrupt.c | 42 +++++++++++---------------- target/s390x/kvm-stub.c | 13 --------- target/s390x/kvm.c | 68 ++++---------------------------------------- target/s390x/kvm_s390x.h | 10 +------ 8 files changed, 123 insertions(+), 116 deletions(-)
hw/intc/s390_flic.c +31 -0
@@ -127,6 +127,34 @@ static int qemu_s390_inject_airq(S390FLICState *fs, uint8_t type,return 0 ; } +static void qemu_s390_inject_service (S390FLICState *fs,uint32_t parm) +{ + +S390CPU *dummy_cpu =s390_cpu_addr2state (0 ); + +/* FIXME: don't inject into dummy CPU */ +cpu_inject_service (dummy_cpu, parm); +} + +static void qemu_s390_inject_io (S390FLICState *fs,uint16_t subchannel_id, +uint16_t subchannel_nr,uint32_t io_int_parm, +uint32_t io_int_word) +{ +S390CPU *dummy_cpu =s390_cpu_addr2state (0 ); + +/* FIXME: don't inject into dummy CPU */ +cpu_inject_io (dummy_cpu, subchannel_id, subchannel_nr, io_int_parm, + io_int_word); +} + +static void qemu_s390_inject_crw_mchk (S390FLICState *fs) +{ +S390CPU *dummy_cpu =s390_cpu_addr2state (0 ); + +/* FIXME: don't inject into dummy CPU */ +cpu_inject_crw_mchk (dummy_cpu); +} +static void qemu_s390_flic_reset (DeviceState *dev) {QEMUS390FLICState *flic =QEMU_S390_FLIC (dev);
@@ -168,6 +196,9 @@ static void qemu_s390_flic_class_init(ObjectClass *oc, void *data) fsc->clear_io_irq = qemu_s390_clear_io_flic; fsc->modify_ais_mode = qemu_s390_modify_ais_mode; fsc->inject_airq = qemu_s390_inject_airq; + fsc->inject_service = qemu_s390_inject_service; + fsc->inject_io = qemu_s390_inject_io; + fsc->inject_crw_mchk = qemu_s390_inject_crw_mchk; }static Property s390_flic_common_properties[] = {
hw/intc/s390_flic_kvm.c +58 -5
78 lines not on this page · raw message
include/hw/s390x/s390_flic.h +5 -0
@@ -66,6 +66,11 @@ typedef struct S390FLICStateClass {int (*modify_ais_mode)(S390FLICState *fs,uint8_t isc,uint16_t mode);int (*inject_airq)(S390FLICState *fs,uint8_t type,uint8_t isc,uint8_t flags); +void (*inject_service)(S390FLICState *fs,uint32_t parm); +void (*inject_io)(S390FLICState *fs,uint16_t subchannel_id, +uint16_t subchannel_nr,uint32_t io_int_parm, +uint32_t io_int_word); +void (*inject_crw_mchk)(S390FLICState *fs); } S390FLICStateClass;#define TYPE_KVM_S390_FLIC "s390-flic-kvm"
target/s390x/cpu.h +6 -1
@@ -740,7 +740,12 @@ void s390_program_interrupt(CPUS390XState *env, uint32_t code, int ilen, uintptr_t ra);/* service interrupts are floating therefore we must not pass an cpustate */ void s390_sclp_extint (uint32_t parm); - +/* FIXME: remove once we have proper floating interrupts in TCG */ +void cpu_inject_service (S390CPU *cpu,uint32_t param); +void cpu_inject_crw_mchk (S390CPU *cpu); +void cpu_inject_io (S390CPU *cpu,uint16_t subchannel_id, +uint16_t subchannel_number,uint32_t io_int_parm, +uint32_t io_int_word);/* mmu_helper.c */ int s390_cpu_virt_mem_rw(S390CPU *cpu, vaddr laddr, uint8_t ar, void *hostbuf,
target/s390x/interrupt.c +17 -25
84 lines not on this page · raw message
target/s390x/kvm-stub.c +0 -13
@@ -12,10 +12,6 @@#include "cpu.h" #include "kvm_s390x.h" -void kvm_s390_service_interrupt (uint32_t parm) -{ -} -void kvm_s390_access_exception (S390CPU *cpu,uint16_t code,uint64_t te_code) { }
@@ -30,15 +26,6 @@ void kvm_s390_program_interrupt(S390CPU *cpu, uint16_t code) { } -void kvm_s390_io_interrupt (uint16_t subchannel_id,uint16_t subchannel_nr, -uint32_t io_int_parm,uint32_t io_int_word) -{ -} - -void kvm_s390_crw_mchk (void ) -{ -} -int kvm_s390_set_cpu_state (S390CPU *cpu,uint8_t cpu_state) {return -ENOSYS ;
target/s390x/kvm.c +5 -63
92 lines not on this page · raw message
target/s390x/kvm_s390x.h +1 -9
@@ -12,17 +12,12 @@struct kvm_s390_irq ; -void kvm_s390_floating_interrupt (struct kvm_s390_irq *irq); -void kvm_s390_service_interrupt (uint32_t parm); +void kvm_s390_floating_interrupt_legacy (struct kvm_s390_irq *irq);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);int kvm_s390_mem_op (S390CPU *cpu,vaddr addr,uint8_t ar,void *hostbuf,int len,bool is_write);void kvm_s390_program_interrupt (S390CPU *cpu,uint16_t code); -void kvm_s390_io_interrupt (uint16_t subchannel_id, -uint16_t subchannel_nr,uint32_t io_int_parm, -uint32_t io_int_word); -void kvm_s390_crw_mchk (void );int kvm_s390_set_cpu_state (S390CPU *cpu,uint8_t cpu_state);void kvm_s390_vcpu_interrupt_pre_save (S390CPU *cpu);int kvm_s390_vcpu_interrupt_post_load (S390CPU *cpu);
@@ -44,7 +39,4 @@ void kvm_s390_crypto_reset(void);void kvm_s390_restart_interrupt (S390CPU *cpu);void kvm_s390_stop_interrupt (S390CPU *cpu); -/* implemented outside of target/s390x/ */ -int kvm_s390_inject_flic (struct kvm_s390_irq *irq); -#endif /* KVM_S390X_H */
Signature · 1 line
2.14.3
PATCH v2 6/18 s390x/flic: no need to call s390_io_interrupt() from flic
In reply to David HildenbrandWe can directly call the right function.
--- hw/intc/s390_flic.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
hw/intc/s390_flic.c +2 -1
@@ -108,6 +108,7 @@ static int qemu_s390_inject_airq(S390FLICState *fs, uint8_t type, uint8_t isc, uint8_t flags) {QEMUS390FLICState *flic =QEMU_S390_FLIC (fs); +S390FLICStateClass *fsc =S390_FLIC_COMMON_GET_CLASS (fs);bool flag = flags &S390_ADAPTER_SUPPRESSIBLE ;uint32_t io_int_word = (isc <<27 ) |IO_INT_WORD_AI ;
@@ -116,7 +117,7 @@ static int qemu_s390_inject_airq(S390FLICState *fs, uint8_t type,return 0 ; } -s390_io_interrupt (0 ,0 ,0 , io_int_word); + fsc->inject_io (fs,0 ,0 ,0 , io_int_word);if (flag && (flic->simm &AIS_MODE_MASK (isc))) { flic->nimm |=AIS_MODE_MASK (isc);
Signature · 1 line
2.14.3
PATCH v2 7/18 s390x/tcg: tolerate wrong wakeups due to floating interrupts
In reply to David HildenbrandThis is a prparation for floating interrupt support and only applies to MTTCG, single threaded TCG works just fine. If a floating interrupt wakes up a VCPU and the CPU thinks it can run (clearing cs->halted), at the point where the interrupt would be delivered, already another VCPU might have picked up the interrupt, resulting in a wakeup without an interrupt (executing wrong code).
It is wrong to let the VCPU continue to execute (the WAIT PSW). Instead, we have to put the VCPU back to sleep.
--- target/s390x/excp_helper.c | 5 +++++ 1 file changed, 5 insertions(+)
target/s390x/excp_helper.c +5 -0
@@ -503,6 +503,11 @@ bool s390_cpu_exec_interrupt(CPUState *cs, int interrupt_request)s390_cpu_do_interrupt (cs);return true; } +if (env->psw.mask &PSW_MASK_WAIT ) { +/* Woken up because of a floating interrupt but it has already +* been delivered. Go back to sleep. */ +cpu_interrupt (CPU (cpu),CPU_INTERRUPT_HALT ); + } }return false; }
Signature · 1 line
2.14.3
Re: [Qemu-devel] [PATCH v2 07/18] s390x/tcg: tolerate wrong wakeups due to floating interrupts
Quoted 1 line · On Wed, 17 Jan 2018 18:40:36 +0100 David Hildenbrand <[email protected]> wrote:
This is a prparation for floating interrupt support and only applies to
s/prparation/preparation/
(can fix while applying)
Quoted 30 lines
MTTCG, single threaded TCG works just fine. If a floating interrupt wakes up a VCPU and the CPU thinks it can run (clearing
cs->halted), at the point where the interrupt would be delivered, already another VCPU might have picked up the interrupt, resulting in a wakeup without an interrupt (executing wrong code).It is wrong to let the VCPU continue to execute (the WAIT PSW). Instead, we have to put the VCPU back to sleep.
Signed-off-by David Hildenbrand <[email protected]>--- target/s390x/excp_helper.c | 5 +++++ 1 file changed, 5 insertions(+)target/s390x/excp_helper.c +5
-0@@ -503,6 +503,11 @@ bool s390_cpu_exec_interrupt(CPUState *cs, int interrupt_request)s390_cpu_do_interrupt (cs);return true; } +if (env->psw.mask &PSW_MASK_WAIT ) { +/* Woken up because of a floating interrupt but it has already +* been delivered. Go back to sleep. */ +cpu_interrupt (CPU (cpu),CPU_INTERRUPT_HALT ); + } }return false; }
PATCH v2 8/18 s390x/flic: make floating interrupts on TCG actually floating
In reply to David HildenbrandMove floating interrupt handling into the flic. Floating interrupts will now be considered by all CPUs, not just CPU #0. While at it, convert I/O interrupts to use a list and make sure we properly consider I/O sub-classes in s390_cpu_has_io_int().
--- hw/intc/s390_flic.c | 144 ++++++++++++++++++++++++++++++++++++++++--- include/hw/s390x/s390_flic.h | 41 ++++++++++++ target/s390x/cpu.c | 8 --- target/s390x/cpu.h | 22 ------- target/s390x/excp_helper.c | 97 ++++++++++------------------- target/s390x/interrupt.c | 52 ++-------------- 6 files changed, 212 insertions(+), 152 deletions(-)
hw/intc/s390_flic.c +134 -10
@@ -128,40 +128,153 @@ static int qemu_s390_inject_airq(S390FLICState *fs, uint8_t type,return 0 ; } +static void qemu_s390_flic_notify (uint32_t type) +{ +CPUState *cs; + +/* +* We have to make all CPUs see CPU_INTERRUPT_HARD, so they might +* consider it. TODO: don't kick/wakeup all VCPUs but try to be +* smarter (using the interrupt type). +*/ +CPU_FOREACH (cs) { +cpu_interrupt (cs,CPU_INTERRUPT_HARD ); + } +} + +uint32_t qemu_s390_flic_dequeue_service (QEMUS390FLICState *flic) +{ +uint32_t tmp; + +g_assert (qemu_mutex_iothread_locked ()); +g_assert (flic->pending &FLIC_PENDING_SERVICE ); + tmp = flic->service_param; + flic->service_param =0 ; + flic->pending &= ~FLIC_PENDING_SERVICE ; + +return tmp; +} + +/* caller has to free the returned object */ +QEMUS390FlicIO *qemu_s390_flic_dequeue_io (QEMUS390FLICState *flic,uint64_t cr6) +{ +QEMUS390FlicIO *io; +uint8_t isc; + +g_assert (qemu_mutex_iothread_locked ()); +if (!(flic->pending &CR6_TO_PENDING_IO (cr6))) { +return NULL ; + } + +for (isc =0 ; isc <8 ; isc++) { +if (QLIST_EMPTY (&flic->io[isc]) || !(cr6 &ISC_TO_ISC_BITS (isc))) { +continue ; + } + io =QLIST_FIRST (&flic->io[isc]); +QLIST_REMOVE (io, next); + +/* update our indicator bit */ +if (QLIST_EMPTY (&flic->io[isc])) { + flic->pending &= ~ISC_TO_PENDING_IO (isc); + } +return io; + } + +return NULL ; +} + +void qemu_s390_flic_dequeue_crw_mchk (QEMUS390FLICState *flic) +{ +g_assert (qemu_mutex_iothread_locked ()); +g_assert (flic->pending &FLIC_PENDING_MCHK_CR ); + flic->pending &= ~FLIC_PENDING_MCHK_CR ; +} +static void qemu_s390_inject_service (S390FLICState *fs,uint32_t parm) { +QEMUS390FLICState *flic =QEMU_S390_FLIC (fs); -S390CPU *dummy_cpu =s390_cpu_addr2state (0 ); +g_assert (qemu_mutex_iothread_locked ()); +/* multiplexing is good enough for sclp - kvm does it internally as well */ + flic->service_param |= parm; + flic->pending |=FLIC_PENDING_SERVICE ; -/* FIXME: don't inject into dummy CPU */ -cpu_inject_service (dummy_cpu, parm); +qemu_s390_flic_notify (FLIC_PENDING_SERVICE ); }static void qemu_s390_inject_io (S390FLICState *fs,uint16_t subchannel_id,uint16_t subchannel_nr,uint32_t io_int_parm,uint32_t io_int_word) { -S390CPU *dummy_cpu =s390_cpu_addr2state (0 ); +const uint8_t isc =IO_INT_WORD_ISC (io_int_word); +QEMUS390FLICState *flic =QEMU_S390_FLIC (fs); +QEMUS390FlicIO *io; -/* FIXME: don't inject into dummy CPU */ -cpu_inject_io (dummy_cpu, subchannel_id, subchannel_nr, io_int_parm, - io_int_word); +g_assert (qemu_mutex_iothread_locked ()); + io =g_new0 (QEMUS390FlicIO,1 ); + io->id = subchannel_id; + io->nr = subchannel_nr; + io->parm = io_int_parm; + io->word = io_int_word; + +QLIST_INSERT_HEAD (&flic->io[isc], io, next); + flic->pending |=ISC_TO_PENDING_IO (isc); + +qemu_s390_flic_notify (ISC_TO_PENDING_IO (isc)); }static void qemu_s390_inject_crw_mchk (S390FLICState *fs) { -S390CPU *dummy_cpu =s390_cpu_addr2state (0 ); +QEMUS390FLICState *flic =QEMU_S390_FLIC (fs); + +g_assert (qemu_mutex_iothread_locked ()); + flic->pending |=FLIC_PENDING_MCHK_CR ; + +qemu_s390_flic_notify (FLIC_PENDING_MCHK_CR ); +} + +bool qemu_s390_flic_has_service (QEMUS390FLICState *flic) +{ +/* called without lock via cc->has_work, will be validated under lock */ +return !!(flic->pending &FLIC_PENDING_SERVICE ); +} + +bool qemu_s390_flic_has_io (QEMUS390FLICState *flic,uint64_t cr6) +{ +/* called without lock via cc->has_work, will be validated under lock */ +return !!(flic->pending &CR6_TO_PENDING_IO (cr6)); +} + +bool qemu_s390_flic_has_crw_mchk (QEMUS390FLICState *flic) +{ +/* called without lock via cc->has_work, will be validated under lock */ +return !!(flic->pending &FLIC_PENDING_MCHK_CR ); +} -/* FIXME: don't inject into dummy CPU */ -cpu_inject_crw_mchk (dummy_cpu); +bool qemu_s390_flic_has_any (QEMUS390FLICState *flic) +{ +g_assert (qemu_mutex_iothread_locked ()); +return !!flic->pending; }static void qemu_s390_flic_reset (DeviceState *dev) {QEMUS390FLICState *flic =QEMU_S390_FLIC (dev); +QEMUS390FlicIO *cur, *next; +int isc; +g_assert (qemu_mutex_iothread_locked ()); flic->simm =0 ; flic->nimm =0 ; + flic->pending =0 ; + +/* remove all pending io interrupts */ +for (isc =0 ; isc <8 ; isc++) { + QLIST_FOREACH_SAFE(cur, &flic->io[isc], next, next) { +QLIST_REMOVE (cur, next); +g_free (cur); + } + } }bool ais_needed (void *opaque)
@@ -183,6 +296,16 @@ static const VMStateDescription qemu_s390_flic_vmstate = { } }; +static void qemu_s390_flic_instance_init (Object *obj) +{ +QEMUS390FLICState *flic =QEMU_S390_FLIC (obj); +int isc; + +for (isc =0 ; isc <8 ; isc++) { +QLIST_INIT (&flic->io[isc]); + } +} +static void qemu_s390_flic_class_init (ObjectClass *oc,void *data) {DeviceClass *dc =DEVICE_CLASS (oc);
@@ -234,6 +357,7 @@ static const TypeInfo qemu_s390_flic_info = { .name = TYPE_QEMU_S390_FLIC, .parent = TYPE_S390_FLIC_COMMON, .instance_size = sizeof(QEMUS390FLICState), + .instance_init = qemu_s390_flic_instance_init, .class_init = qemu_s390_flic_class_init, };
include/hw/s390x/s390_flic.h +41 -0
59 lines not on this page · raw message
target/s390x/cpu.c +0 -8
@@ -99,7 +99,6 @@ static void s390_cpu_initial_reset(CPUState *s) {S390CPU *cpu =S390_CPU (s);CPUS390XState *env = &cpu->env; -int i;s390_cpu_reset (s);/* initial reset does not clear everything! */
@@ -115,9 +114,6 @@ static void s390_cpu_initial_reset(CPUState *s) env->gbea =1 ; env->pfault_token =-1UL ; -for (i =0 ; i <ARRAY_SIZE (env->io_index); i++) { - env->io_index[i] =-1 ; - }/* tininess for underflow is detected before rounding */ set_float_detect_tininess(float_tininess_before_rounding,
@@ -135,7 +131,6 @@ static void s390_cpu_full_reset(CPUState *s)S390CPU *cpu =S390_CPU (s);S390CPUClass *scc =S390_CPU_GET_CLASS (cpu);CPUS390XState *env = &cpu->env; -int i; scc->parent_reset (s); cpu->env.sigp_order =0 ;
@@ -151,9 +146,6 @@ static void s390_cpu_full_reset(CPUState *s) env->gbea =1 ; env->pfault_token =-1UL ; -for (i =0 ; i <ARRAY_SIZE (env->io_index); i++) { - env->io_index[i] =-1 ; - }/* tininess for underflow is detected before rounding */ set_float_detect_tininess(float_tininess_before_rounding,
target/s390x/cpu.h +0 -22
@@ -53,8 +53,6 @@#define MMU_USER_IDX 0 -#define MAX_IO_QUEUE 16 -#define S390_MAX_CPUS 248 typedef struct PSW {
@@ -62,13 +60,6 @@ typedef struct PSW {uint64_t addr; }PSW ; -typedef struct IOIntQueue { -uint16_t id; -uint16_t nr; -uint32_t parm; -uint32_t word; -}IOIntQueue ; -struct CPUS390XState {uint64_t regs[16 ];/* GP registers */ /*
@@ -113,13 +104,9 @@ struct CPUS390XState {uint64_t cregs[16 ];/* control registers */ -IOIntQueue io_queue[MAX_IO_QUEUE ][8 ]; -int pending_int; -uint32_t service_param;uint16_t external_call_addr;DECLARE_BITMAP (emergency_signals,S390_MAX_CPUS ); -int io_index[8 ];uint64_t ckc;uint64_t cputm;
@@ -398,9 +385,6 @@ static inline void cpu_get_tb_cpu_state(CPUS390XState* env, target_ulong *pc,#define EXCP_IO 7/* I/O interrupt */ #define EXCP_MCHK 8/* machine check */ -#define INTERRUPT_IO (1 << 0) -#define INTERRUPT_MCHK (1 << 1) -#define INTERRUPT_EXT_SERVICE (1 << 2)#define INTERRUPT_EXT_CPU_TIMER (1 << 3)#define INTERRUPT_EXT_CLOCK_COMPARATOR (1 << 4)#define INTERRUPT_EXTERNAL_CALL (1 << 5)
@@ -740,12 +724,6 @@ void s390_program_interrupt(CPUS390XState *env, uint32_t code, int ilen, uintptr_t ra);/* service interrupts are floating therefore we must not pass an cpustate */ void s390_sclp_extint (uint32_t parm); -/* FIXME: remove once we have proper floating interrupts in TCG */ -void cpu_inject_service (S390CPU *cpu,uint32_t param); -void cpu_inject_crw_mchk (S390CPU *cpu); -void cpu_inject_io (S390CPU *cpu,uint16_t subchannel_id, -uint16_t subchannel_number,uint32_t io_int_parm, -uint32_t io_int_word);/* mmu_helper.c */ int s390_cpu_virt_mem_rw(S390CPU *cpu, vaddr laddr, uint8_t ar, void *hostbuf,
target/s390x/excp_helper.c +31 -66
152 lines not on this page · raw message
target/s390x/interrupt.c +6 -46
100 lines not on this page · raw message
Signature · 1 line
2.14.3
PATCH v2 9/18 s390x/tcg: implement TEST PENDING INTERRUPTION
In reply to David HildenbrandUse s390_cpu_virt_mem_write() so we can actually revert what we did (re-inject the dequeued IO interrupt).
--- target/s390x/helper.h | 1 + target/s390x/insn-data.def | 1 + target/s390x/misc_helper.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++ target/s390x/translate.c | 8 +++++++ 4 files changed, 64 insertions(+)
target/s390x/helper.h +1 -0
@@ -170,6 +170,7 @@ DEF_HELPER_4(schm, void, env, i64, i64, i64) DEF_HELPER_3(ssch, void, env, i64, i64) DEF_HELPER_2(stcrw, void, env, i64) DEF_HELPER_3(stsch, void, env, i64, i64) +DEF_HELPER_2(tpi, i32, env, i64) DEF_HELPER_3(tsch, void, env, i64, i64) DEF_HELPER_2(chsc, void, env, i64)#endif
target/s390x/insn-data.def +1 -0
@@ -1063,6 +1063,7 @@ C(0xb233, SSCH, S, Z, 0, insn, 0, 0, ssch, 0) C(0xb239, STCRW, S, Z, 0, insn, 0, 0, stcrw, 0) C(0xb234, STSCH, S, Z, 0, insn, 0, 0, stsch, 0) + C(0xb236, TPI , S, Z, la2, 0, 0, 0, tpi, 0) C(0xb235, TSCH, S, Z, 0, insn, 0, 0, tsch, 0) /* ??? Not listed in PoO ninth edition, but there's a linux driver that uses it: "A CHSC subchannel is usually present on LPAR only." */
target/s390x/misc_helper.c +54 -0
66 lines not on this page · raw message
target/s390x/translate.c +8 -0
@@ -4199,6 +4199,14 @@ static ExitStatus op_stcrw(DisasContext *s, DisasOps *o)return NO_EXIT ; } +static ExitStatus op_tpi (DisasContext *s,DisasOps *o) +{ +check_privileged (s); +gen_helper_tpi (cc_op, cpu_env, o->addr1); +set_cc_static (s); +return NO_EXIT ; +} +static ExitStatus op_tsch (DisasContext *s,DisasOps *o) {check_privileged (s);
Signature · 1 line
2.14.3
PATCH v2 10/18 s390x/flic: implement qemu_s390_clear_io_flic()
In reply to David HildenbrandNow that we have access to the io interrupts, we can implement clear_io_irq() for TCG.
--- hw/intc/s390_flic.c | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-)
hw/intc/s390_flic.c +29 -2
@@ -79,8 +79,35 @@ static void qemu_s390_release_adapter_routes(S390FLICState *fs,static int qemu_s390_clear_io_flic (S390FLICState *fs,uint16_t subchannel_id,uint16_t subchannel_nr) { -/* Fixme TCG */ -return -ENOSYS ; +QEMUS390FLICState *flic =QEMU_S390_FLIC (fs); +QEMUS390FlicIO *cur, *next; +uint8_t isc; + +g_assert (qemu_mutex_iothread_locked ()); +if (!(flic->pending &FLIC_PENDING_IO )) { +return 0 ; + } + +/* check all iscs */ +for (isc =0 ; isc <8 ; isc++) { +if (QLIST_EMPTY (&flic->io[isc])) { +continue ; + } + +/* search and delete any matching one */ + QLIST_FOREACH_SAFE(cur, &flic->io[isc], next, next) { +if (cur->id == subchannel_id && cur->nr == subchannel_nr) { +QLIST_REMOVE (cur, next); +g_free (cur); + } + } + +/* update our indicator bit */ +if (QLIST_EMPTY (&flic->io[isc])) { + flic->pending &= ~ISC_TO_PENDING_IO (isc); + } + } +return 0 ; } static int qemu_s390_modify_ais_mode(S390FLICState *fs, uint8_t isc,
Signature · 1 line
2.14.3
PATCH v2 11/18 s390x/flic: optimize CPU wakeup for TCG
In reply to David HildenbrandKicking all CPUs on every floating interrupt is far from efficient. Let's optimize it at least a little bit.
--- hw/intc/s390_flic.c | 31 +++++++++++++++++++++++++++++-- target/s390x/cpu.h | 4 ++++ target/s390x/internal.h | 5 ----- 3 files changed, 33 insertions(+), 7 deletions(-)
hw/intc/s390_flic.c +29 -2
@@ -161,10 +161,37 @@ static void qemu_s390_flic_notify(uint32_t type)/* * We have to make all CPUs see CPU_INTERRUPT_HARD, so they might -* consider it. TODO: don't kick/wakeup all VCPUs but try to be -* smarter (using the interrupt type). +* consider it. We will kick all running CPUs and only relevant +* sleeping ones. */ CPU_FOREACH (cs) { +S390CPU *cpu =S390_CPU (cs); + + cs->interrupt_request |=CPU_INTERRUPT_HARD ; + +/* ignore CPUs that are not sleeping */ +if (s390_cpu_get_state (cpu) !=CPU_STATE_OPERATING && +s390_cpu_get_state (cpu) !=CPU_STATE_LOAD ) { +continue ; + } + +/* we always kick running CPUs for now, this is tricky */ +if (cs->halted) { +/* don't check for subclasses, CPUs double check when waking up */ +if (type &FLIC_PENDING_SERVICE ) { +if (!(cpu->env.psw.mask &PSW_MASK_EXT )) { +continue ; + } + }else if (type &FLIC_PENDING_IO ) { +if (!(cpu->env.psw.mask &PSW_MASK_IO )) { +continue ; + } + }else if (type &FLIC_PENDING_MCHK_CR ) { +if (!(cpu->env.psw.mask &PSW_MASK_MCHECK )) { +continue ; + } + } + }cpu_interrupt (cs,CPU_INTERRUPT_HARD ); } }
target/s390x/cpu.h +4 -0
@@ -691,6 +691,10 @@ static inline unsigned int s390_cpu_set_state(uint8_t cpu_state, S390CPU *cpu) return 0; }#endif /* CONFIG_USER_ONLY */ +static inline uint8_t s390_cpu_get_state (S390CPU *cpu) +{ +return cpu->env.cpu_state; +}/* cpu_models.c */
target/s390x/internal.h +0 -5
@@ -278,11 +278,6 @@ static inline void s390_do_cpu_full_reset(CPUState *cs, run_on_cpu_data arg)cpu_reset (cs); } -static inline uint8_t s390_cpu_get_state (S390CPU *cpu) -{ -return cpu->env.cpu_state; -} -/* arch_dump.c */ int s390_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
Signature · 1 line
2.14.3
PATCH v2 12/18 s390x: fix size + content of STSI blocks
In reply to David HildenbrandAll blocks are 4k in size, which is only true for two of them right now. Also some reserved fields were wrong, fix it and convert all reserved fields to u8.
This also fixes the LPAR part output in /proc/sysinfo under TCG. (for now, everything was indicated as 0)
While at it, introduce typedefs for these structs and use it in KVM code. Not changing misc_helper.c as that will be overhauled soon.
--- target/s390x/cpu.h | 46 ++++++++++++++++++++++++++-------------------- target/s390x/kvm.c | 2 +- 2 files changed, 27 insertions(+), 21 deletions(-)
target/s390x/cpu.h +26 -20
@@ -436,29 +436,31 @@ static inline void setcc(S390CPU *cpu, uint64_t cc)#define STSI_R1_SEL2_MASK 0x000000000000ffffULL/* Basic Machine Configuration */ -struct sysib_111 { -uint32_t res1[8 ]; +typedef struct sysib_111 { +uint8_t res1[32 ];uint8_t manuf[16 ];uint8_t type[4 ];uint8_t res2[12 ];uint8_t model[16 ];uint8_t sequence[16 ];uint8_t plant[4 ]; -uint8_t res3[156 ]; -}; +uint8_t res3[3996 ]; +}sysib_111 ; +QEMU_BUILD_BUG_ON (sizeof (sysib_111) !=4096 );/* Basic Machine CPU */ -struct sysib_121 { -uint32_t res1[80 ]; +typedef struct sysib_121 { +uint8_t res1[80 ];uint8_t sequence[16 ];uint8_t plant[4 ];uint8_t res2[2 ];uint16_t cpu_addr; -uint8_t res3[152 ]; -}; +uint8_t res3[3992 ]; +}sysib_121 ; +QEMU_BUILD_BUG_ON (sizeof (sysib_121) !=4096 );/* Basic Machine CPUs */ -struct sysib_122 { +typedef struct sysib_122 { uint8_t res1[32]; uint32_t capability; uint16_t total_cpus;
@@ -466,21 +468,23 @@ struct sysib_122 {uint16_t standby_cpus;uint16_t reserved_cpus;uint16_t adjustments[2026 ]; -}; +} sysib_122; +QEMU_BUILD_BUG_ON (sizeof (sysib_122) !=4096 );/* LPAR CPU */ -struct sysib_221 { -uint32_t res1[80 ]; +typedef struct sysib_221 { +uint8_t res1[80 ];uint8_t sequence[16 ];uint8_t plant[4 ];uint16_t cpu_id;uint16_t cpu_addr; -uint8_t res3[152 ]; -}; +uint8_t res3[3992 ]; +}sysib_221 ; +QEMU_BUILD_BUG_ON (sizeof (sysib_221) !=4096 );/* LPAR CPUs */ -struct sysib_222 { -uint32_t res1[32 ]; +typedef struct sysib_222 { + uint8_t res1[32]; uint16_t lpar_num; uint8_t res2; uint8_t lcpuc;
@@ -493,11 +497,12 @@ struct sysib_222 {uint8_t res3[16 ];uint16_t dedicated_cpus;uint16_t shared_cpus; -uint8_t res4[180 ]; -}; +uint8_t res4[4020 ]; +} sysib_222; +QEMU_BUILD_BUG_ON (sizeof (sysib_222) !=4096 );/* VM CPUs */ -struct sysib_322 { +typedef struct sysib_322 { uint8_t res1[31]; uint8_t count; struct {
@@ -516,7 +521,8 @@ struct sysib_322 { } vm[8 ];uint8_t res4[1504 ];uint8_t ext_names[8 ][256 ]; -}; +} sysib_322; +QEMU_BUILD_BUG_ON (sizeof (sysib_322) !=4096 );/* MMU defines */ #define _ASCE_ORIGIN ~0xfffULL/* segment table origin */
target/s390x/kvm.c +1 -1
@@ -1666,7 +1666,7 @@ static int handle_tsch(S390CPU *cpu)static void insert_stsi_3_2_2 (S390CPU *cpu,__u64 addr,uint8_t ar) { -struct sysib_322 sysib; +sysib_322 sysib;int del;if (s390_cpu_virt_mem_read (cpu, addr, ar, &sysib,sizeof (sysib))) {
Signature · 1 line
2.14.3
Re: [Qemu-devel] [PATCH v2 12/18] s390x: fix size + content of STSI blocks
Quoted 29 lines · On Wed, 17 Jan 2018 18:40:41 +0100 David Hildenbrand <[email protected]> wrote:
All blocks are 4k in size, which is only true for two of them right now. Also some reserved fields were wrong, fix it and convert all reserved fields to u8.
This also fixes the LPAR part output in
/proc/sysinfounder TCG. (for now, everything was indicated as 0)While at it, introduce typedefs for these structs and use it in KVM code. Not changing
misc_helper.cas that will be overhauled soon.Reviewed-by Thomas Huth <[email protected]>Signed-off-by David Hildenbrand <[email protected]>--- target/s390x/cpu.h | 46 ++++++++++++++++++++++++++-------------------- target/s390x/kvm.c | 2 +- 2 files changed, 27 insertions(+), 21 deletions(-)target/s390x/cpu.h +2
-2@@ -436,29 +436,31 @@ static inline void setcc(S390CPU *cpu, uint64_t cc)#define STSI_R1_SEL2_MASK 0x000000000000ffffULL/* Basic Machine Configuration */ -struct sysib_111 { -uint32_t res1[8 ]; +typedef struct sysib_111 { + uint8_t res1[32];
target/s390x/cpu.h static inline void setcc(S390CPU *cpu, uint64_t cc) · line 448
Quoted 10 lines
target/s390x/cpu.h +2
-2uint8_t manuf[16 ];uint8_t type[4 ];uint8_t res2[12 ];uint8_t model[16 ];uint8_t sequence[16 ];uint8_t plant[4 ]; -uint8_t res3[156 ]; -}; +uint8_t res3[3996 ]; +} sysib_111;
Do you want to CamelCase this?
Quoted 1 line
target/s390x/cpu.h +1
-0+QEMU_BUILD_BUG_ON (sizeof (sysib_111) !=4096 );
Re: [Qemu-devel] [PATCH v2 12/18] s390x: fix size + content of STSI blocks
Quoted 36 lines · Cornelia Huck
Quoted 33 lines · On Wed, 17 Jan 2018 18:40:41 +0100 David Hildenbrand <[email protected]> wrote:
All blocks are 4k in size, which is only true for two of them right now. Also some reserved fields were wrong, fix it and convert all reserved fields to u8.
This also fixes the LPAR part output in
/proc/sysinfounder TCG. (for now, everything was indicated as 0)While at it, introduce typedefs for these structs and use it in KVM code. Not changing
misc_helper.cas that will be overhauled soon.Reviewed-by Thomas Huth <[email protected]>Signed-off-by David Hildenbrand <[email protected]>--- target/s390x/cpu.h | 46 ++++++++++++++++++++++++++-------------------- target/s390x/kvm.c | 2 +- 2 files changed, 27 insertions(+), 21 deletions(-)target/s390x/cpu.h +2
-2@@ -436,29 +436,31 @@ static inline void setcc(S390CPU *cpu, uint64_t cc)#define STSI_R1_SEL2_MASK 0x000000000000ffffULL/* Basic Machine Configuration */ -struct sysib_111 { -uint32_t res1[8 ]; +typedef struct sysib_111 { + uint8_t res1[32]; uint8_t manuf[16]; uint8_t type[4]; uint8_t res2[12]; uint8_t model[16];
Quoted 8 lines
target/s390x/cpu.h static inline void setcc(S390CPU *cpu, uint64_t cc) · line 448
Quoted 6 lines
target/s390x/cpu.h +2
-2uint8_t sequence[16 ];uint8_t plant[4 ]; -uint8_t res3[156 ]; -}; +uint8_t res3[3996 ]; +} sysib_111;Do you want to CamelCase this?
"System-information block" "SysIB" ?
Quoted 2 lines
Quoted 2 lines
target/s390x/cpu.h +1
-0+QEMU_BUILD_BUG_ON (sizeof (sysib_111) !=4096 );
Signature · 3 lines
Thanks, David / dhildenb
Re: [Qemu-devel] [PATCH v2 12/18] s390x: fix size + content of STSI blocks
Quoted 46 lines · On Thu, 25 Jan 2018 14:15:45 +0100 David Hildenbrand <[email protected]> wrote:
Quoted 36 lines · Cornelia Huck
Quoted 33 lines · On Wed, 17 Jan 2018 18:40:41 +0100 David Hildenbrand <[email protected]> wrote:
All blocks are 4k in size, which is only true for two of them right now. Also some reserved fields were wrong, fix it and convert all reserved fields to u8.
This also fixes the LPAR part output in
/proc/sysinfounder TCG. (for now, everything was indicated as 0)While at it, introduce typedefs for these structs and use it in KVM code. Not changing
misc_helper.cas that will be overhauled soon.Reviewed-by Thomas Huth <[email protected]>Signed-off-by David Hildenbrand <[email protected]>--- target/s390x/cpu.h | 46 ++++++++++++++++++++++++++-------------------- target/s390x/kvm.c | 2 +- 2 files changed, 27 insertions(+), 21 deletions(-)target/s390x/cpu.h +2
-2@@ -436,29 +436,31 @@ static inline void setcc(S390CPU *cpu, uint64_t cc)#define STSI_R1_SEL2_MASK 0x000000000000ffffULL/* Basic Machine Configuration */ -struct sysib_111 { -uint32_t res1[8 ]; +typedef struct sysib_111 { + uint8_t res1[32]; uint8_t manuf[16]; uint8_t type[4]; uint8_t res2[12]; uint8_t model[16];Quoted 8 lines
target/s390x/cpu.h static inline void setcc(S390CPU *cpu, uint64_t cc) · line 448
Quoted 6 lines
target/s390x/cpu.h +2
-2uint8_t sequence[16 ];uint8_t plant[4 ]; -uint8_t res3[156 ]; -}; +uint8_t res3[3996 ]; +} sysib_111;Do you want to CamelCase this?
Quoted 1 line
"System-information block" "SysIB" ?
Looks good to me.
Quoted 5 lines
Quoted 3 lines
Quoted 3 lines
target/s390x/cpu.h +1
-0+QEMU_BUILD_BUG_ON (sizeof (sysib_111) !=4096 );
Re: [Qemu-devel] [qemu-s390x] [PATCH v2 12/18] s390x: fix size + content of STSI blocks
Quoted 49 lines · Cornelia Huck
Quoted 46 lines · On Thu, 25 Jan 2018 14:15:45 +0100 David Hildenbrand <[email protected]> wrote:
Quoted 44 lines · Cornelia Huck
Quoted 29 lines · On Wed, 17 Jan 2018 18:40:41 +0100 David Hildenbrand <[email protected]> wrote:
All blocks are 4k in size, which is only true for two of them right now. Also some reserved fields were wrong, fix it and convert all reserved fields to u8.
This also fixes the LPAR part output in
/proc/sysinfounder TCG. (for now, everything was indicated as 0)While at it, introduce typedefs for these structs and use it in KVM code. Not changing
misc_helper.cas that will be overhauled soon.Reviewed-by Thomas Huth <[email protected]>Signed-off-by David Hildenbrand <[email protected]>--- target/s390x/cpu.h | 46 ++++++++++++++++++++++++++-------------------- target/s390x/kvm.c | 2 +- 2 files changed, 27 insertions(+), 21 deletions(-)target/s390x/cpu.h +2
-2@@ -436,29 +436,31 @@ static inline void setcc(S390CPU *cpu, uint64_t cc)#define STSI_R1_SEL2_MASK 0x000000000000ffffULL/* Basic Machine Configuration */ -struct sysib_111 { -uint32_t res1[8 ]; +typedef struct sysib_111 { + uint8_t res1[32];target/s390x/cpu.h static inline void setcc(S390CPU *cpu, uint64_t cc) · line 448
Quoted 10 lines
target/s390x/cpu.h +2
-2uint8_t manuf[16 ];uint8_t type[4 ];uint8_t res2[12 ];uint8_t model[16 ];uint8_t sequence[16 ];uint8_t plant[4 ]; -uint8_t res3[156 ]; -}; +uint8_t res3[3996 ]; +} sysib_111;Do you want to CamelCase this?
Quoted 3 lines
Quoted 1 line
"System-information block" "SysIB" ?
Looks good to me.
If there are no further comments, I can resend.
Signature · 3 lines
Thanks, David / dhildenb
Re: [Qemu-devel] [qemu-s390x] [PATCH v2 12/18] s390x: fix size + content of STSI blocks
Quoted 1 line · On Mon, 29 Jan 2018 10:42:33 +0100 David Hildenbrand <[email protected]> wrote:
If there are no further comments, I can resend.
Other than the wrong cr check, I did not have any complaints.
PATCH v2 13/18 s390x/tcg: STSI overhaul
In reply to David HildenbrandCurrent STSI implementation is a mess, so let's rewrite it.
Problems fixed by this patch:
1) The order of exceptions/when recognized is wrong.
2) We have to store to virtual address space, not absolute.
3) Alignment check of the block is missing.
3) The SMP information is not indicated.
While at it:
a) Make the code look nicer
- get rid of nesting levels
- use struct initialization instead of initializing to zero
- rename a misspelled field and rename function code defines
- use a union and have only one write statement
- use cpu_to_beX()
b) Indicate the VM name/extended name + UUID just like KVM does
c) Indicate that all LPAR CPUs we fake are dedicated
d) Add a comment why we fake being a KVM guest
e) Give our guest as default the name "TCGguest"
f) Fake the same CPU information we have in our Guest for all layers
While at it, get rid of "potential_page_fault()" by forwarding the retaddr properly.
The result is best verified by looking at "/proc/sysinfo" in the guest when specifying on the qemu command line
-uuid "74738ff5-5367-5958-9aee-98fffdcd1876" \
-name "extra long guest name"
--- target/s390x/cpu.h | 22 +++-- target/s390x/misc_helper.c | 212 ++++++++++++++++++++++++--------------------- 2 files changed, 131 insertions(+), 103 deletions(-)
target/s390x/cpu.h +16 -6
@@ -425,11 +425,11 @@ static inline void setcc(S390CPU *cpu, uint64_t cc) }/* STSI */ -#define STSI_LEVEL_MASK 0x00000000f0000000ULL -#define STSI_LEVEL_CURRENT 0x0000000000000000ULL -#define STSI_LEVEL_1 0x0000000010000000ULL -#define STSI_LEVEL_2 0x0000000020000000ULL -#define STSI_LEVEL_3 0x0000000030000000ULL +#define STSI_R0_FC_MASK 0x00000000f0000000ULL +#define STSI_R0_FC_CURRENT 0x0000000000000000ULL +#define STSI_R0_FC_LEVEL_1 0x0000000010000000ULL +#define STSI_R0_FC_LEVEL_2 0x0000000020000000ULL +#define STSI_R0_FC_LEVEL_3 0x0000000030000000ULL#define STSI_R0_RESERVED_MASK 0x000000000fffff00ULL#define STSI_R0_SEL1_MASK 0x00000000000000ffULL#define STSI_R1_RESERVED_MASK 0x00000000ffff0000ULL
@@ -464,7 +464,7 @@ typedef struct sysib_122 {uint8_t res1[32 ];uint32_t capability;uint16_t total_cpus; -uint16_t active_cpus; +uint16_t conf_cpus;uint16_t standby_cpus;uint16_t reserved_cpus;uint16_t adjustments[2026 ];
@@ -524,6 +524,16 @@ typedef struct sysib_322 { } sysib_322;QEMU_BUILD_BUG_ON (sizeof (sysib_322) !=4096 ); +typedef union sysib { +sysib_111 sysib_111; +sysib_121 sysib_121; +sysib_122 sysib_122; +sysib_221 sysib_221; +sysib_222 sysib_222; +sysib_322 sysib_322; +}sysib ; +QEMU_BUILD_BUG_ON (sizeof (sysib) !=4096 ); +/* MMU defines */ #define _ASCE_ORIGIN ~0xfffULL/* segment table origin */ #define _ASCE_SUBSPACE 0x200/* subspace group control */
target/s390x/misc_helper.c +115 -97
253 lines not on this page · raw message
Signature · 1 line
2.14.3
PATCH v2 14/18 s390x/tcg: remove SMP warning
In reply to David HildenbrandWe should be pretty good in shape now. Floating interrupts are working and atomic instructions should be atomic.
--- hw/s390x/s390-virtio-ccw.c | 4 ---- 1 file changed, 4 deletions(-)
hw/s390x/s390-virtio-ccw.c +0 -4
@@ -78,10 +78,6 @@ static void s390_init_cpus(MachineState *machine)MachineClass *mc =MACHINE_GET_CLASS (machine);int i; -if (tcg_enabled () && max_cpus >1 ) { -error_report ("WARNING: SMP support on s390x is experimental!" ); - } -/* initialize possible_cpus */ mc->possible_cpu_arch_ids (machine);
Signature · 1 line
2.14.3
PATCH v2 15/18 configure: s390x supports mttcg now
In reply to David Hildenbrands390x is ready. Most likely we are missing some pieces, but it should already be in pretty good shape now.
--- configure | 1 + 1 file changed, 1 insertion(+)
configure +1 -0
@@ -6581,6 +6581,7 @@ case "$target_name" in echo "TARGET_ABI32=y" >> $config_target_mak ;; s390x) + mttcg=yes gdb_xml_files="s390x-core64.xml s390-acr.xml s390-fpr.xml s390-vx.xml s390-cr.xml s390-virt.xml s390-gs.xml" ;; tilegx)
Signature · 1 line
2.14.3
PATCH v2 16/18 s390x/tcg: cache the qemu flic in a central function
In reply to David HildenbrandThis avoids tons of conversions when handling interrupts.
--- hw/intc/s390_flic.c | 23 +++++++++++++++++------ include/hw/s390x/s390_flic.h | 1 + target/s390x/interrupt.c | 6 +++--- target/s390x/misc_helper.c | 2 +- 4 files changed, 22 insertions(+), 10 deletions(-)
hw/intc/s390_flic.c +17 -6
@@ -22,6 +22,17 @@#include "qapi/error.h" #include "hw/s390x/s390-virtio-ccw.h" +QEMUS390FLICState *s390_get_qemu_flic (S390FLICState *fs) +{ +static QEMUS390FLICState *flic; + +if (!flic) { +/* we only have one flic device, so this is fine to cache */ + flic =QEMU_S390_FLIC (fs); + } +return flic; +} +S390FLICState *s390_get_flic (void ) {static S390FLICState *fs;
@@ -79,7 +90,7 @@ static void qemu_s390_release_adapter_routes(S390FLICState *fs,static int qemu_s390_clear_io_flic (S390FLICState *fs,uint16_t subchannel_id,uint16_t subchannel_nr) { -QEMUS390FLICState *flic =QEMU_S390_FLIC (fs); +QEMUS390FLICState *flic =s390_get_qemu_flic (fs);QEMUS390FlicIO *cur, *next;uint8_t isc;
@@ -113,7 +124,7 @@ static int qemu_s390_clear_io_flic(S390FLICState *fs, uint16_t subchannel_id,static int qemu_s390_modify_ais_mode (S390FLICState *fs,uint8_t isc,uint16_t mode) { -QEMUS390FLICState *flic =QEMU_S390_FLIC (fs); +QEMUS390FLICState *flic =s390_get_qemu_flic (fs);switch (mode) {case SIC_IRQ_MODE_ALL :
@@ -134,7 +145,7 @@ static int qemu_s390_modify_ais_mode(S390FLICState *fs, uint8_t isc,static int qemu_s390_inject_airq (S390FLICState *fs,uint8_t type,uint8_t isc,uint8_t flags) { -QEMUS390FLICState *flic =QEMU_S390_FLIC (fs); +QEMUS390FLICState *flic =s390_get_qemu_flic (fs);S390FLICStateClass *fsc =S390_FLIC_COMMON_GET_CLASS (fs);bool flag = flags &S390_ADAPTER_SUPPRESSIBLE ;uint32_t io_int_word = (isc <<27 ) |IO_INT_WORD_AI ;
@@ -246,7 +257,7 @@ void qemu_s390_flic_dequeue_crw_mchk(QEMUS390FLICState *flic)static void qemu_s390_inject_service (S390FLICState *fs,uint32_t parm) { -QEMUS390FLICState *flic =QEMU_S390_FLIC (fs); +QEMUS390FLICState *flic =s390_get_qemu_flic (fs);g_assert (qemu_mutex_iothread_locked ());/* multiplexing is good enough for sclp - kvm does it internally as well */
@@ -261,7 +272,7 @@ static void qemu_s390_inject_io(S390FLICState *fs, uint16_t subchannel_id, uint32_t io_int_word) {const uint8_t isc =IO_INT_WORD_ISC (io_int_word); -QEMUS390FLICState *flic =QEMU_S390_FLIC (fs); +QEMUS390FLICState *flic =s390_get_qemu_flic (fs);QEMUS390FlicIO *io;g_assert (qemu_mutex_iothread_locked ());
@@ -279,7 +290,7 @@ static void qemu_s390_inject_io(S390FLICState *fs, uint16_t subchannel_id,static void qemu_s390_inject_crw_mchk (S390FLICState *fs) { -QEMUS390FLICState *flic =QEMU_S390_FLIC (fs); +QEMUS390FLICState *flic =s390_get_qemu_flic (fs);g_assert (qemu_mutex_iothread_locked ()); flic->pending |=FLIC_PENDING_MCHK_CR ;
include/hw/s390x/s390_flic.h +1 -0
@@ -135,6 +135,7 @@ bool qemu_s390_flic_has_any(QEMUS390FLICState *flic);void s390_flic_init (void );S390FLICState *s390_get_flic (void ); +QEMUS390FLICState *s390_get_qemu_flic (S390FLICState *fs);bool ais_needed (void *opaque);#endif /* HW_S390_FLIC_H */
target/s390x/interrupt.c +3 -3
@@ -158,7 +158,7 @@ void s390_crw_mchk(void)bool s390_cpu_has_mcck_int (S390CPU *cpu) { -QEMUS390FLICState *flic =QEMU_S390_FLIC (s390_get_flic ()); +QEMUS390FLICState *flic =s390_get_qemu_flic (s390_get_flic ());CPUS390XState *env = &cpu->env;if (!(env->psw.mask &PSW_MASK_MCHECK )) {
@@ -176,7 +176,7 @@ bool s390_cpu_has_mcck_int(S390CPU *cpu)bool s390_cpu_has_ext_int (S390CPU *cpu) { -QEMUS390FLICState *flic =QEMU_S390_FLIC (s390_get_flic ()); +QEMUS390FLICState *flic =s390_get_qemu_flic (s390_get_flic ());CPUS390XState *env = &cpu->env;if (!(env->psw.mask &PSW_MASK_EXT )) {
@@ -218,7 +218,7 @@ bool s390_cpu_has_ext_int(S390CPU *cpu)bool s390_cpu_has_io_int (S390CPU *cpu) { -QEMUS390FLICState *flic =QEMU_S390_FLIC (s390_get_flic ()); +QEMUS390FLICState *flic =s390_get_qemu_flic (s390_get_flic ());CPUS390XState *env = &cpu->env;if (!(env->psw.mask &PSW_MASK_IO )) {
target/s390x/misc_helper.c +1 -1
@@ -452,7 +452,7 @@ uint32_t HELPER(tpi)(CPUS390XState *env, uint64_t addr) {const uintptr_t ra =GETPC ();S390CPU *cpu =s390_env_get_cpu (env); -QEMUS390FLICState *flic =QEMU_S390_FLIC (s390_get_flic ()); +QEMUS390FLICState *flic =s390_get_qemu_flic (s390_get_flic ());QEMUS390FlicIO *io =NULL ;LowCore *lowcore;
Signature · 1 line
2.14.3
PATCH v2 17/18 s390x/kvm: cache the kvm flic in a central function
In reply to David HildenbrandThis avoids tons of conversions when handling interrupts.
--- hw/intc/s390_flic_kvm.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-)
hw/intc/s390_flic_kvm.c +16 -5
@@ -35,6 +35,17 @@ typedef struct KVMS390FLICState {bool clear_io_supported; } KVMS390FLICState; +static KVMS390FLICState *s390_get_kvm_flic (S390FLICState *fs) +{ +static KVMS390FLICState *flic; + +if (!flic) { +/* we only have one flic device, so this is fine to cache */ + flic =KVM_S390_FLIC (fs); + } +return flic; +} +/** * flic_get_all_irqs - store all pending irqs in buffer * @buf: pointer to buffer which is passed to kernel
@@ -117,7 +128,7 @@ static void kvm_s390_inject_flic(S390FLICState *fs, struct kvm_s390_irq *irq)int r;if (use_flic) { - r =flic_enqueue_irqs (irq,sizeof (*irq),KVM_S390_FLIC (fs)); + r =flic_enqueue_irqs (irq,sizeof (*irq),s390_get_kvm_flic (fs));if (r == -ENOSYS ) { use_flic = false; }
@@ -174,7 +185,7 @@ static void kvm_s390_inject_crw_mchk(S390FLICState *fs)static int kvm_s390_clear_io_flic (S390FLICState *fs,uint16_t subchannel_id,uint16_t subchannel_nr) { -KVMS390FLICState *flic =KVM_S390_FLIC (fs); +KVMS390FLICState *flic =s390_get_kvm_flic (fs);int rc;uint32_t sid = subchannel_id <<16 | subchannel_nr;struct kvm_device_attr attr = {
@@ -192,7 +203,7 @@ static int kvm_s390_clear_io_flic(S390FLICState *fs, uint16_t subchannel_id,static int kvm_s390_modify_ais_mode (S390FLICState *fs,uint8_t isc,uint16_t mode) { -KVMS390FLICState *flic =KVM_S390_FLIC (fs); +KVMS390FLICState *flic =s390_get_kvm_flic (fs);struct kvm_s390_ais_req req = { .isc = isc, .mode = mode,
@@ -212,7 +223,7 @@ static int kvm_s390_modify_ais_mode(S390FLICState *fs, uint8_t isc,static int kvm_s390_inject_airq (S390FLICState *fs,uint8_t type,uint8_t isc,uint8_t flags) { -KVMS390FLICState *flic =KVM_S390_FLIC (fs); +KVMS390FLICState *flic =s390_get_kvm_flic (fs);uint32_t id =css_get_adapter_id (type, isc);struct kvm_device_attr attr = { .group =KVM_DEV_FLIC_AIRQ_INJECT ,
@@ -301,7 +312,7 @@ static int kvm_s390_io_adapter_map(S390FLICState *fs, uint32_t id, .group = KVM_DEV_FLIC_ADAPTER_MODIFY, .addr = (uint64_t)&req, }; -KVMS390FLICState *flic =KVM_S390_FLIC (fs); +KVMS390FLICState *flic =s390_get_kvm_flic (fs);int r;if (!kvm_gsi_routing_enabled ()) {
Signature · 1 line
2.14.3
Re: [Qemu-devel] [PATCH v2 17/18] s390x/kvm: cache the kvm flic in a central function
Quoted 3 lines · David Hildenbrand
This avoids tons of conversions when handling interrupts.
Signed-off-by David Hildenbrand <[email protected]>
Quoted 72 lines
--- hw/intc/s390_flic_kvm.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-)hw/intc/s390_flic_kvm.c +16
-5@@ -35,6 +35,17 @@ typedef struct KVMS390FLICState {bool clear_io_supported; } KVMS390FLICState; +static KVMS390FLICState *s390_get_kvm_flic (S390FLICState *fs) +{ +static KVMS390FLICState *flic; + +if (!flic) { +/* we only have one flic device, so this is fine to cache */ + flic =KVM_S390_FLIC (fs); + } +return flic; +} +/** * flic_get_all_irqs - store all pending irqs in buffer * @buf: pointer to buffer which is passed to kernel @@ -117,7 +128,7 @@ static void kvm_s390_inject_flic(S390FLICState *fs, struct kvm_s390_irq *irq)int r;if (use_flic) { - r =flic_enqueue_irqs (irq,sizeof (*irq),KVM_S390_FLIC (fs)); + r =flic_enqueue_irqs (irq,sizeof (*irq),s390_get_kvm_flic (fs));if (r == -ENOSYS ) { use_flic = false; }@@ -174,7 +185,7 @@ static void kvm_s390_inject_crw_mchk(S390FLICState *fs)static int kvm_s390_clear_io_flic (S390FLICState *fs,uint16_t subchannel_id,uint16_t subchannel_nr) { -KVMS390FLICState *flic =KVM_S390_FLIC (fs); +KVMS390FLICState *flic =s390_get_kvm_flic (fs);int rc;uint32_t sid = subchannel_id <<16 | subchannel_nr;struct kvm_device_attr attr = {@@ -192,7 +203,7 @@ static int kvm_s390_clear_io_flic(S390FLICState *fs, uint16_t subchannel_id,static int kvm_s390_modify_ais_mode (S390FLICState *fs,uint8_t isc,uint16_t mode) { -KVMS390FLICState *flic =KVM_S390_FLIC (fs); +KVMS390FLICState *flic =s390_get_kvm_flic (fs);struct kvm_s390_ais_req req = { .isc = isc, .mode = mode,@@ -212,7 +223,7 @@ static int kvm_s390_modify_ais_mode(S390FLICState *fs, uint8_t isc,static int kvm_s390_inject_airq (S390FLICState *fs,uint8_t type,uint8_t isc,uint8_t flags) { -KVMS390FLICState *flic =KVM_S390_FLIC (fs); +KVMS390FLICState *flic =s390_get_kvm_flic (fs);uint32_t id =css_get_adapter_id (type, isc);struct kvm_device_attr attr = { .group =KVM_DEV_FLIC_AIRQ_INJECT ,@@ -301,7 +312,7 @@ static int kvm_s390_io_adapter_map(S390FLICState *fs, uint32_t id, .group = KVM_DEV_FLIC_ADAPTER_MODIFY, .addr = (uint64_t)&req, }; -KVMS390FLICState *flic =KVM_S390_FLIC (fs); +KVMS390FLICState *flic =s390_get_kvm_flic (fs);int r;if (!kvm_gsi_routing_enabled ()) {
PATCH v2 18/18 s390x/flic: cache the common flic class in a central function
In reply to David HildenbrandThis avoids tons of conversions when handling interrupts.
--- hw/intc/s390_flic.c | 13 ++++++++++++- hw/s390x/css.c | 10 +++++----- hw/s390x/virtio-ccw.c | 4 ++-- include/hw/s390x/s390_flic.h | 1 + target/s390x/interrupt.c | 6 +++--- 5 files changed, 23 insertions(+), 11 deletions(-)
hw/intc/s390_flic.c +12 -1
@@ -22,6 +22,17 @@#include "qapi/error.h" #include "hw/s390x/s390-virtio-ccw.h" +S390FLICStateClass *s390_get_flic_class (S390FLICState *fs) +{ +static S390FLICStateClass *class; + +if (!class) { +/* we only have one flic device, so this is fine to cache */ + class =S390_FLIC_COMMON_GET_CLASS (fs); + } +return class; +} +QEMUS390FLICState *s390_get_qemu_flic (S390FLICState *fs) {static QEMUS390FLICState *flic;
@@ -146,7 +157,7 @@ static int qemu_s390_inject_airq(S390FLICState *fs, uint8_t type, uint8_t isc, uint8_t flags) {QEMUS390FLICState *flic =s390_get_qemu_flic (fs); -S390FLICStateClass *fsc =S390_FLIC_COMMON_GET_CLASS (fs); +S390FLICStateClass *fsc =s390_get_flic_class (fs);bool flag = flags &S390_ADAPTER_SUPPRESSIBLE ;uint32_t io_int_word = (isc <<27 ) |IO_INT_WORD_AI ;
hw/s390x/css.c +5 -5
@@ -439,7 +439,7 @@ static int s390_io_adapter_map(AdapterInfo *adapter, uint64_t map_addr, bool do_map) {S390FLICState *fs =s390_get_flic (); -S390FLICStateClass *fsc =S390_FLIC_COMMON_GET_CLASS (fs); +S390FLICStateClass *fsc =s390_get_flic_class (fs);return fsc->io_adapter_map (fs, adapter->adapter_id, map_addr, do_map); }
@@ -520,7 +520,7 @@ void css_register_io_adapters(CssIoAdapterType type, bool swap, bool maskable,int ret, isc;IoAdapter *adapter;S390FLICState *fs =s390_get_flic (); -S390FLICStateClass *fsc =S390_FLIC_COMMON_GET_CLASS (fs); +S390FLICStateClass *fsc =s390_get_flic_class (fs);/* * Disallow multiple registrations for the same device type.
@@ -566,7 +566,7 @@ static void css_clear_io_interrupt(uint16_t subchannel_id,Error *err =NULL ;static bool no_clear_irq;S390FLICState *fs =s390_get_flic (); -S390FLICStateClass *fsc =S390_FLIC_COMMON_GET_CLASS (fs); +S390FLICStateClass *fsc =s390_get_flic_class (fs);int r;if (unlikely (no_clear_irq)) {
@@ -640,7 +640,7 @@ void css_conditional_io_interrupt(SubchDev *sch)int css_do_sic (CPUS390XState *env,uint8_t isc,uint16_t mode) {S390FLICState *fs =s390_get_flic (); -S390FLICStateClass *fsc =S390_FLIC_COMMON_GET_CLASS (fs); +S390FLICStateClass *fsc =s390_get_flic_class (fs);int r;if (env->psw.mask &PSW_MASK_PSTATE ) {
@@ -666,7 +666,7 @@ out:void css_adapter_interrupt (CssIoAdapterType type,uint8_t isc) {S390FLICState *fs =s390_get_flic (); -S390FLICStateClass *fsc =S390_FLIC_COMMON_GET_CLASS (fs); +S390FLICStateClass *fsc =s390_get_flic_class (fs);uint32_t io_int_word = (isc <<27 ) |IO_INT_WORD_AI ;IoAdapter *adapter = channel_subsys.io_adapters[type][isc];
hw/s390x/virtio-ccw.c +2 -2
@@ -1111,7 +1111,7 @@ static int virtio_ccw_setup_irqroutes(VirtioCcwDevice *dev, int nvqs)VirtIODevice *vdev =virtio_bus_get_device (&dev->bus);int ret;S390FLICState *fs =s390_get_flic (); -S390FLICStateClass *fsc =S390_FLIC_COMMON_GET_CLASS (fs); +S390FLICStateClass *fsc =s390_get_flic_class (fs); ret =virtio_ccw_get_mappings (dev);if (ret) {
@@ -1129,7 +1129,7 @@ static int virtio_ccw_setup_irqroutes(VirtioCcwDevice *dev, int nvqs)static void virtio_ccw_release_irqroutes (VirtioCcwDevice *dev,int nvqs) {S390FLICState *fs =s390_get_flic (); -S390FLICStateClass *fsc =S390_FLIC_COMMON_GET_CLASS (fs); +S390FLICStateClass *fsc =s390_get_flic_class (fs); fsc->release_adapter_routes (fs, &dev->routes); }
include/hw/s390x/s390_flic.h +1 -0
@@ -136,6 +136,7 @@ void s390_flic_init(void);S390FLICState *s390_get_flic (void );QEMUS390FLICState *s390_get_qemu_flic (S390FLICState *fs); +S390FLICStateClass *s390_get_flic_class (S390FLICState *fs);bool ais_needed (void *opaque);#endif /* HW_S390_FLIC_H */
target/s390x/interrupt.c +3 -3
@@ -134,7 +134,7 @@ void cpu_inject_stop(S390CPU *cpu)void s390_sclp_extint (uint32_t parm) {S390FLICState *fs =s390_get_flic (); -S390FLICStateClass *fsc =S390_FLIC_COMMON_GET_CLASS (fs); +S390FLICStateClass *fsc =s390_get_flic_class (fs); fsc->inject_service (fs, parm); }
@@ -143,7 +143,7 @@ void s390_io_interrupt(uint16_t subchannel_id, uint16_t subchannel_nr, uint32_t io_int_parm, uint32_t io_int_word) {S390FLICState *fs =s390_get_flic (); -S390FLICStateClass *fsc =S390_FLIC_COMMON_GET_CLASS (fs); +S390FLICStateClass *fsc =s390_get_flic_class (fs); fsc->inject_io (fs, subchannel_id, subchannel_nr, io_int_parm, io_int_word); }
@@ -151,7 +151,7 @@ void s390_io_interrupt(uint16_t subchannel_id, uint16_t subchannel_nr,void s390_crw_mchk (void ) {S390FLICState *fs =s390_get_flic (); -S390FLICStateClass *fsc =S390_FLIC_COMMON_GET_CLASS (fs); +S390FLICStateClass *fsc =s390_get_flic_class (fs); fsc->inject_crw_mchk (fs); }
Signature · 1 line
2.14.3
Quoted 7 lines · On Wed, 17 Jan 2018 18:40:29 +0100 David Hildenbrand <[email protected]> wrote:
This patch series implements floating interrupt support for TCG and fixes STSI so we can remove warnings related to s390x SMP and MTTCG.
KVM code has to be touched in order to factor out the injection routines into the flic ("s390x/flic: factor out injection of floating interrupts"). Basic testing didn't reveal any problems so far.
Quoted 6 lines
With this series I am now able to run fedora 26/27 and Ubuntu 17.10+ with 16 VCPUs (MTTCG) on a 8CPU host, doing a make -j16 in the guest. I got nasty stalls in the guest beforehand.
Now also included: More flic related caching to avoid recurring conversions.
Basically, seems good to me. Will play with it a bit more.
I'd also love some reviews/acks.
Quoted 7 lines · On Wed, 17 Jan 2018 18:40:29 +0100 David Hildenbrand <[email protected]> wrote:
This patch series implements floating interrupt support for TCG and fixes STSI so we can remove warnings related to s390x SMP and MTTCG.
KVM code has to be touched in order to factor out the injection routines into the flic ("s390x/flic: factor out injection of floating interrupts"). Basic testing didn't reveal any problems so far.
Quoted 6 lines
With this series I am now able to run fedora 26/27 and Ubuntu 17.10+ with 16 VCPUs (MTTCG) on a 8CPU host, doing a make -j16 in the guest. I got nasty stalls in the guest beforehand.
Now also included: More flic related caching to avoid recurring conversions.
Hm...
(qemu) device_add virtio-net-ccw,id=xxx
(qemu) **
ERROR:/home/cohuck/git/qemu/target/s390x/excp_helper.c:342:do_mchk_interrupt: assertion failed: (env->cregs[14] & CR0_SERVICE_SC) Aborted (core dumped)
Quoted 17 lines · On Thu, 25 Jan 2018 13:42:41 +0100 Cornelia Huck <[email protected]> wrote:
Quoted 7 lines · On Wed, 17 Jan 2018 18:40:29 +0100 David Hildenbrand <[email protected]> wrote:
This patch series implements floating interrupt support for TCG and fixes STSI so we can remove warnings related to s390x SMP and MTTCG.
KVM code has to be touched in order to factor out the injection routines into the flic ("s390x/flic: factor out injection of floating interrupts"). Basic testing didn't reveal any problems so far.
Quoted 6 lines
With this series I am now able to run fedora 26/27 and Ubuntu 17.10+ with 16 VCPUs (MTTCG) on a 8CPU host, doing a make -j16 in the guest. I got nasty stalls in the guest beforehand.
Now also included: More flic related caching to avoid recurring conversions.
Quoted 6 lines
Hm...
(qemu)
device_addvirtio-net-ccw,id=xxx
(qemu) **
ERROR:/home/cohuck/git/qemu/target/s390x/excp_helper.c:342:do_mchk_interrupt: assertion failed: (env->cregs[14] &CR0_SERVICE_SC) Aborted (core dumped)
Works much better if you check for CR14_CHANNEL_REPORT_SC instead :)
Quoted 20 lines · Cornelia Huck
Quoted 17 lines · On Thu, 25 Jan 2018 13:42:41 +0100 Cornelia Huck <[email protected]> wrote:
Quoted 13 lines · On Wed, 17 Jan 2018 18:40:29 +0100 David Hildenbrand <[email protected]> wrote:
This patch series implements floating interrupt support for TCG and fixes STSI so we can remove warnings related to s390x SMP and MTTCG.
KVM code has to be touched in order to factor out the injection routines into the flic ("s390x/flic: factor out injection of floating interrupts"). Basic testing didn't reveal any problems so far.
With this series I am now able to run fedora 26/27 and Ubuntu 17.10+ with 16 VCPUs (MTTCG) on a 8CPU host, doing a make -j16 in the guest. I got nasty stalls in the guest beforehand.
Now also included: More flic related caching to avoid recurring conversions.
Quoted 9 lines
Quoted 6 lines
Hm...
(qemu)
device_addvirtio-net-ccw,id=xxx
(qemu) **
ERROR:/home/cohuck/git/qemu/target/s390x/excp_helper.c:342:do_mchk_interrupt: assertion failed: (env->cregs[14] &CR0_SERVICE_SC) Aborted (core dumped)Works much better if you check for
CR14_CHANNEL_REPORT_SCinstead :)
Thanks for testing and spotting the wrong assert!
Signature · 3 lines
Thanks, David / dhildenb
Quoted 23 lines · David Hildenbrand
Quoted 22 lines · Cornelia Huck
Quoted 19 lines · On Thu, 25 Jan 2018 13:42:41 +0100 Cornelia Huck <[email protected]> wrote:
Quoted 7 lines · On Wed, 17 Jan 2018 18:40:29 +0100 David Hildenbrand <[email protected]> wrote:
This patch series implements floating interrupt support for TCG and fixes STSI so we can remove warnings related to s390x SMP and MTTCG.
KVM code has to be touched in order to factor out the injection routines into the flic ("s390x/flic: factor out injection of floating interrupts"). Basic testing didn't reveal any problems so far.
Quoted 6 lines
With this series I am now able to run fedora 26/27 and Ubuntu 17.10+ with 16 VCPUs (MTTCG) on a 8CPU host, doing a make -j16 in the guest. I got nasty stalls in the guest beforehand.
Now also included: More flic related caching to avoid recurring conversions.
Hm...
Quoted 8 lines
Quoted 6 lines
Quoted 4 lines
(qemu)
device_addvirtio-net-ccw,id=xxx
(qemu) **
ERROR:/home/cohuck/git/qemu/target/s390x/excp_helper.c:342:do_mchk_interrupt: assertion failed: (env->cregs[14] &CR0_SERVICE_SC) Aborted (core dumped)Works much better if you check for
CR14_CHANNEL_REPORT_SCinstead :)Thanks for testing and spotting the wrong assert!
We definitely need to get tests/virtio-net-test.c running on s390x, too ;-)
Thomas