Skip to content

Commit

Permalink
s390x: Add missing vcpu reset functions
Browse files Browse the repository at this point in the history
Up to now we only had an ioctl to reset vcpu data QEMU couldn't reach
for the initial reset, which was also called for the clear reset. To
be architecture compliant, we also need to clear local interrupts on a
normal reset.

Because of this and the upcoming protvirt support we need to add
ioctls for the missing clear and normal resets.

Signed-off-by: Janosch Frank <[email protected]>
Reviewed-by: Thomas Huth <[email protected]>
Acked-by: David Hildenbrand <[email protected]>
Message-Id: <[email protected]>
Signed-off-by: Cornelia Huck <[email protected]>
  • Loading branch information
frankjaa authored and cohuck committed Feb 26, 2020
1 parent ddda374 commit b91a039
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 12 deletions.
14 changes: 12 additions & 2 deletions target/s390x/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,18 @@ static void s390_cpu_reset(CPUState *s, cpu_reset_type type)
}

/* Reset state inside the kernel that we cannot access yet from QEMU. */
if (kvm_enabled() && type != S390_CPU_RESET_NORMAL) {
kvm_s390_reset_vcpu(cpu);
if (kvm_enabled()) {
switch (type) {
case S390_CPU_RESET_CLEAR:
kvm_s390_reset_vcpu_clear(cpu);
break;
case S390_CPU_RESET_INITIAL:
kvm_s390_reset_vcpu_initial(cpu);
break;
case S390_CPU_RESET_NORMAL:
kvm_s390_reset_vcpu_normal(cpu);
break;
}
}
}

Expand Down
10 changes: 9 additions & 1 deletion target/s390x/kvm-stub.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,15 @@ void kvm_s390_cmma_reset(void)
{
}

void kvm_s390_reset_vcpu(S390CPU *cpu)
void kvm_s390_reset_vcpu_initial(S390CPU *cpu)
{
}

void kvm_s390_reset_vcpu_clear(S390CPU *cpu)
{
}

void kvm_s390_reset_vcpu_normal(S390CPU *cpu)
{
}

Expand Down
42 changes: 34 additions & 8 deletions target/s390x/kvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ static int cap_s390_irq;
static int cap_ri;
static int cap_gs;
static int cap_hpage_1m;
static int cap_vcpu_resets;

static int active_cmma;

Expand Down Expand Up @@ -342,6 +343,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
cap_async_pf = kvm_check_extension(s, KVM_CAP_ASYNC_PF);
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_vcpu_resets = kvm_check_extension(s, KVM_CAP_S390_VCPU_RESETS);

if (!kvm_check_extension(s, KVM_CAP_S390_GMAP)
|| !kvm_check_extension(s, KVM_CAP_S390_COW)) {
Expand Down Expand Up @@ -406,17 +408,41 @@ int kvm_arch_destroy_vcpu(CPUState *cs)
return 0;
}

void kvm_s390_reset_vcpu(S390CPU *cpu)
static void kvm_s390_reset_vcpu(S390CPU *cpu, unsigned long type)
{
CPUState *cs = CPU(cpu);

/* The initial reset call is needed here to reset in-kernel
* vcpu data that we can't access directly from QEMU
* (i.e. with older kernels which don't support sync_regs/ONE_REG).
* Before this ioctl cpu_synchronize_state() is called in common kvm
* code (kvm-all) */
if (kvm_vcpu_ioctl(cs, KVM_S390_INITIAL_RESET, NULL)) {
error_report("Initial CPU reset failed on CPU %i", cs->cpu_index);
/*
* The reset call is needed here to reset in-kernel vcpu data that
* we can't access directly from QEMU (i.e. with older kernels
* which don't support sync_regs/ONE_REG). Before this ioctl
* cpu_synchronize_state() is called in common kvm code
* (kvm-all).
*/
if (kvm_vcpu_ioctl(cs, type)) {
error_report("CPU reset failed on CPU %i type %lx",
cs->cpu_index, type);
}
}

void kvm_s390_reset_vcpu_initial(S390CPU *cpu)
{
kvm_s390_reset_vcpu(cpu, KVM_S390_INITIAL_RESET);
}

void kvm_s390_reset_vcpu_clear(S390CPU *cpu)
{
if (cap_vcpu_resets) {
kvm_s390_reset_vcpu(cpu, KVM_S390_CLEAR_RESET);
} else {
kvm_s390_reset_vcpu(cpu, KVM_S390_INITIAL_RESET);
}
}

void kvm_s390_reset_vcpu_normal(S390CPU *cpu)
{
if (cap_vcpu_resets) {
kvm_s390_reset_vcpu(cpu, KVM_S390_NORMAL_RESET);
}
}

Expand Down
4 changes: 3 additions & 1 deletion target/s390x/kvm_s390x.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ int kvm_s390_assign_subch_ioeventfd(EventNotifier *notifier, uint32_t sch,
int vq, bool assign);
int kvm_s390_cmma_active(void);
void kvm_s390_cmma_reset(void);
void kvm_s390_reset_vcpu(S390CPU *cpu);
void kvm_s390_reset_vcpu_clear(S390CPU *cpu);
void kvm_s390_reset_vcpu_normal(S390CPU *cpu);
void kvm_s390_reset_vcpu_initial(S390CPU *cpu);
int kvm_s390_set_mem_limit(uint64_t new_limit, uint64_t *hw_limit);
void kvm_s390_set_max_pagesize(uint64_t pagesize, Error **errp);
void kvm_s390_crypto_reset(void);
Expand Down

0 comments on commit b91a039

Please sign in to comment.