Commit 4956aa3b authored by Paolo Bonzini's avatar Paolo Bonzini

Merge tag 'kvm-s390-next-4.17-1' of...

Merge tag 'kvm-s390-next-4.17-1' of git://git.kernel.org/pub/scm/linux/kernel/git/kvms390/linux into HEAD

KVM: s390: fixes and features

- more kvm stat counters
- virtio gpu plumbing. The 3 non-KVM/s390 patches have Acks from
  Bartlomiej Zolnierkiewicz, Heiko Carstens and Greg Kroah-Hartman
  but all belong together to make virtio-gpu work as a tty. So
  I carried them in the KVM/s390 tree.
- document some KVM_CAPs
- cpu-model only facilities
- cleanups
parents 2d7921c4 ccc40c53
...@@ -4555,3 +4555,33 @@ Parameters: none ...@@ -4555,3 +4555,33 @@ Parameters: none
This capability indicates if the flic device will be able to get/set the This capability indicates if the flic device will be able to get/set the
AIS states for migration via the KVM_DEV_FLIC_AISM_ALL attribute and allows AIS states for migration via the KVM_DEV_FLIC_AISM_ALL attribute and allows
to discover this without having to create a flic device. to discover this without having to create a flic device.
8.14 KVM_CAP_S390_PSW
Architectures: s390
This capability indicates that the PSW is exposed via the kvm_run structure.
8.15 KVM_CAP_S390_GMAP
Architectures: s390
This capability indicates that the user space memory used as guest mapping can
be anywhere in the user memory address space, as long as the memory slots are
aligned and sized to a segment (1MB) boundary.
8.16 KVM_CAP_S390_COW
Architectures: s390
This capability indicates that the user space memory used as guest mapping can
use copy-on-write semantics as well as dirty pages tracking via read-only page
tables.
8.17 KVM_CAP_S390_BPB
Architectures: s390
This capability indicates that kvm will implement the interfaces to handle
reset, migration and nested KVM for branch prediction blocking. The stfle
facility 82 should not be provided to the guest without this capability.
...@@ -294,6 +294,7 @@ struct kvm_vcpu_stat { ...@@ -294,6 +294,7 @@ struct kvm_vcpu_stat {
u64 exit_userspace; u64 exit_userspace;
u64 exit_null; u64 exit_null;
u64 exit_external_request; u64 exit_external_request;
u64 exit_io_request;
u64 exit_external_interrupt; u64 exit_external_interrupt;
u64 exit_stop_request; u64 exit_stop_request;
u64 exit_validity; u64 exit_validity;
...@@ -310,16 +311,29 @@ struct kvm_vcpu_stat { ...@@ -310,16 +311,29 @@ struct kvm_vcpu_stat {
u64 exit_program_interruption; u64 exit_program_interruption;
u64 exit_instr_and_program; u64 exit_instr_and_program;
u64 exit_operation_exception; u64 exit_operation_exception;
u64 deliver_ckc;
u64 deliver_cputm;
u64 deliver_external_call; u64 deliver_external_call;
u64 deliver_emergency_signal; u64 deliver_emergency_signal;
u64 deliver_service_signal; u64 deliver_service_signal;
u64 deliver_virtio_interrupt; u64 deliver_virtio;
u64 deliver_stop_signal; u64 deliver_stop_signal;
u64 deliver_prefix_signal; u64 deliver_prefix_signal;
u64 deliver_restart_signal; u64 deliver_restart_signal;
u64 deliver_program_int; u64 deliver_program;
u64 deliver_io_int; u64 deliver_io;
u64 deliver_machine_check;
u64 exit_wait_state; u64 exit_wait_state;
u64 inject_ckc;
u64 inject_cputm;
u64 inject_external_call;
u64 inject_emergency_signal;
u64 inject_mchk;
u64 inject_pfault_init;
u64 inject_program;
u64 inject_restart;
u64 inject_set_prefix;
u64 inject_stop_signal;
u64 instruction_epsw; u64 instruction_epsw;
u64 instruction_gs; u64 instruction_gs;
u64 instruction_io_other; u64 instruction_io_other;
...@@ -644,7 +658,12 @@ struct kvm_vcpu_arch { ...@@ -644,7 +658,12 @@ struct kvm_vcpu_arch {
}; };
struct kvm_vm_stat { struct kvm_vm_stat {
ulong remote_tlb_flush; u64 inject_io;
u64 inject_float_mchk;
u64 inject_pfault_done;
u64 inject_service_signal;
u64 inject_virtio;
u64 remote_tlb_flush;
}; };
struct kvm_arch_memory_slot { struct kvm_arch_memory_slot {
...@@ -792,6 +811,7 @@ struct kvm_arch{ ...@@ -792,6 +811,7 @@ struct kvm_arch{
int css_support; int css_support;
int use_irqchip; int use_irqchip;
int use_cmma; int use_cmma;
int use_pfmfi;
int user_cpu_state_ctrl; int user_cpu_state_ctrl;
int user_sigp; int user_sigp;
int user_stsi; int user_stsi;
......
...@@ -22,8 +22,8 @@ typedef struct { ...@@ -22,8 +22,8 @@ typedef struct {
unsigned int has_pgste:1; unsigned int has_pgste:1;
/* The mmu context uses storage keys. */ /* The mmu context uses storage keys. */
unsigned int use_skey:1; unsigned int use_skey:1;
/* The mmu context uses CMMA. */ /* The mmu context uses CMM. */
unsigned int use_cmma:1; unsigned int uses_cmm:1;
} mm_context_t; } mm_context_t;
#define INIT_MM_CONTEXT(name) \ #define INIT_MM_CONTEXT(name) \
......
...@@ -31,7 +31,7 @@ static inline int init_new_context(struct task_struct *tsk, ...@@ -31,7 +31,7 @@ static inline int init_new_context(struct task_struct *tsk,
(current->mm && current->mm->context.alloc_pgste); (current->mm && current->mm->context.alloc_pgste);
mm->context.has_pgste = 0; mm->context.has_pgste = 0;
mm->context.use_skey = 0; mm->context.use_skey = 0;
mm->context.use_cmma = 0; mm->context.uses_cmm = 0;
#endif #endif
switch (mm->context.asce_limit) { switch (mm->context.asce_limit) {
case _REGION2_SIZE: case _REGION2_SIZE:
......
...@@ -221,6 +221,8 @@ static void __init conmode_default(void) ...@@ -221,6 +221,8 @@ static void __init conmode_default(void)
SET_CONSOLE_SCLP; SET_CONSOLE_SCLP;
#endif #endif
} }
if (IS_ENABLED(CONFIG_VT) && IS_ENABLED(CONFIG_DUMMY_CONSOLE))
conswitchp = &dummy_con;
} }
#ifdef CONFIG_CRASH_DUMP #ifdef CONFIG_CRASH_DUMP
......
...@@ -1050,8 +1050,7 @@ static int kvm_s390_shadow_tables(struct gmap *sg, unsigned long saddr, ...@@ -1050,8 +1050,7 @@ static int kvm_s390_shadow_tables(struct gmap *sg, unsigned long saddr,
rc = gmap_shadow_r2t(sg, saddr, rfte.val, *fake); rc = gmap_shadow_r2t(sg, saddr, rfte.val, *fake);
if (rc) if (rc)
return rc; return rc;
/* fallthrough */ } /* fallthrough */
}
case ASCE_TYPE_REGION2: { case ASCE_TYPE_REGION2: {
union region2_table_entry rste; union region2_table_entry rste;
...@@ -1077,8 +1076,7 @@ static int kvm_s390_shadow_tables(struct gmap *sg, unsigned long saddr, ...@@ -1077,8 +1076,7 @@ static int kvm_s390_shadow_tables(struct gmap *sg, unsigned long saddr,
rc = gmap_shadow_r3t(sg, saddr, rste.val, *fake); rc = gmap_shadow_r3t(sg, saddr, rste.val, *fake);
if (rc) if (rc)
return rc; return rc;
/* fallthrough */ } /* fallthrough */
}
case ASCE_TYPE_REGION3: { case ASCE_TYPE_REGION3: {
union region3_table_entry rtte; union region3_table_entry rtte;
...@@ -1113,8 +1111,7 @@ static int kvm_s390_shadow_tables(struct gmap *sg, unsigned long saddr, ...@@ -1113,8 +1111,7 @@ static int kvm_s390_shadow_tables(struct gmap *sg, unsigned long saddr,
rc = gmap_shadow_sgt(sg, saddr, rtte.val, *fake); rc = gmap_shadow_sgt(sg, saddr, rtte.val, *fake);
if (rc) if (rc)
return rc; return rc;
/* fallthrough */ } /* fallthrough */
}
case ASCE_TYPE_SEGMENT: { case ASCE_TYPE_SEGMENT: {
union segment_table_entry ste; union segment_table_entry ste;
......
...@@ -50,18 +50,6 @@ u8 kvm_s390_get_ilen(struct kvm_vcpu *vcpu) ...@@ -50,18 +50,6 @@ u8 kvm_s390_get_ilen(struct kvm_vcpu *vcpu)
return ilen; return ilen;
} }
static int handle_noop(struct kvm_vcpu *vcpu)
{
switch (vcpu->arch.sie_block->icptcode) {
case 0x10:
vcpu->stat.exit_external_request++;
break;
default:
break; /* nothing */
}
return 0;
}
static int handle_stop(struct kvm_vcpu *vcpu) static int handle_stop(struct kvm_vcpu *vcpu)
{ {
struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
...@@ -465,8 +453,11 @@ int kvm_handle_sie_intercept(struct kvm_vcpu *vcpu) ...@@ -465,8 +453,11 @@ int kvm_handle_sie_intercept(struct kvm_vcpu *vcpu)
switch (vcpu->arch.sie_block->icptcode) { switch (vcpu->arch.sie_block->icptcode) {
case ICPT_EXTREQ: case ICPT_EXTREQ:
vcpu->stat.exit_external_request++;
return 0;
case ICPT_IOREQ: case ICPT_IOREQ:
return handle_noop(vcpu); vcpu->stat.exit_io_request++;
return 0;
case ICPT_INST: case ICPT_INST:
rc = handle_instruction(vcpu); rc = handle_instruction(vcpu);
break; break;
......
...@@ -391,6 +391,7 @@ static int __must_check __deliver_cpu_timer(struct kvm_vcpu *vcpu) ...@@ -391,6 +391,7 @@ static int __must_check __deliver_cpu_timer(struct kvm_vcpu *vcpu)
struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
int rc; int rc;
vcpu->stat.deliver_cputm++;
trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_INT_CPU_TIMER, trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_INT_CPU_TIMER,
0, 0); 0, 0);
...@@ -410,6 +411,7 @@ static int __must_check __deliver_ckc(struct kvm_vcpu *vcpu) ...@@ -410,6 +411,7 @@ static int __must_check __deliver_ckc(struct kvm_vcpu *vcpu)
struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
int rc; int rc;
vcpu->stat.deliver_ckc++;
trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_INT_CLOCK_COMP, trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_INT_CLOCK_COMP,
0, 0); 0, 0);
...@@ -595,6 +597,7 @@ static int __must_check __deliver_machine_check(struct kvm_vcpu *vcpu) ...@@ -595,6 +597,7 @@ static int __must_check __deliver_machine_check(struct kvm_vcpu *vcpu)
trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id,
KVM_S390_MCHK, KVM_S390_MCHK,
mchk.cr14, mchk.mcic); mchk.cr14, mchk.mcic);
vcpu->stat.deliver_machine_check++;
rc = __write_machine_check(vcpu, &mchk); rc = __write_machine_check(vcpu, &mchk);
} }
return rc; return rc;
...@@ -710,7 +713,7 @@ static int __must_check __deliver_prog(struct kvm_vcpu *vcpu) ...@@ -710,7 +713,7 @@ static int __must_check __deliver_prog(struct kvm_vcpu *vcpu)
ilen = pgm_info.flags & KVM_S390_PGM_FLAGS_ILC_MASK; ilen = pgm_info.flags & KVM_S390_PGM_FLAGS_ILC_MASK;
VCPU_EVENT(vcpu, 3, "deliver: program irq code 0x%x, ilen:%d", VCPU_EVENT(vcpu, 3, "deliver: program irq code 0x%x, ilen:%d",
pgm_info.code, ilen); pgm_info.code, ilen);
vcpu->stat.deliver_program_int++; vcpu->stat.deliver_program++;
trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_PROGRAM_INT, trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_PROGRAM_INT,
pgm_info.code, 0); pgm_info.code, 0);
...@@ -899,7 +902,7 @@ static int __must_check __deliver_virtio(struct kvm_vcpu *vcpu) ...@@ -899,7 +902,7 @@ static int __must_check __deliver_virtio(struct kvm_vcpu *vcpu)
VCPU_EVENT(vcpu, 4, VCPU_EVENT(vcpu, 4,
"deliver: virtio parm: 0x%x,parm64: 0x%llx", "deliver: virtio parm: 0x%x,parm64: 0x%llx",
inti->ext.ext_params, inti->ext.ext_params2); inti->ext.ext_params, inti->ext.ext_params2);
vcpu->stat.deliver_virtio_interrupt++; vcpu->stat.deliver_virtio++;
trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id,
inti->type, inti->type,
inti->ext.ext_params, inti->ext.ext_params,
...@@ -975,7 +978,7 @@ static int __must_check __deliver_io(struct kvm_vcpu *vcpu, ...@@ -975,7 +978,7 @@ static int __must_check __deliver_io(struct kvm_vcpu *vcpu,
inti->io.subchannel_id >> 1 & 0x3, inti->io.subchannel_id >> 1 & 0x3,
inti->io.subchannel_nr); inti->io.subchannel_nr);
vcpu->stat.deliver_io_int++; vcpu->stat.deliver_io++;
trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id,
inti->type, inti->type,
((__u32)inti->io.subchannel_id << 16) | ((__u32)inti->io.subchannel_id << 16) |
...@@ -1004,7 +1007,7 @@ static int __must_check __deliver_io(struct kvm_vcpu *vcpu, ...@@ -1004,7 +1007,7 @@ static int __must_check __deliver_io(struct kvm_vcpu *vcpu,
VCPU_EVENT(vcpu, 4, "%s isc %u", "deliver: I/O (AI/gisa)", isc); VCPU_EVENT(vcpu, 4, "%s isc %u", "deliver: I/O (AI/gisa)", isc);
memset(&io, 0, sizeof(io)); memset(&io, 0, sizeof(io));
io.io_int_word = isc_to_int_word(isc); io.io_int_word = isc_to_int_word(isc);
vcpu->stat.deliver_io_int++; vcpu->stat.deliver_io++;
trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id,
KVM_S390_INT_IO(1, 0, 0, 0), KVM_S390_INT_IO(1, 0, 0, 0),
((__u32)io.subchannel_id << 16) | ((__u32)io.subchannel_id << 16) |
...@@ -1268,6 +1271,7 @@ static int __inject_prog(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq) ...@@ -1268,6 +1271,7 @@ static int __inject_prog(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq)
{ {
struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
vcpu->stat.inject_program++;
VCPU_EVENT(vcpu, 3, "inject: program irq code 0x%x", irq->u.pgm.code); VCPU_EVENT(vcpu, 3, "inject: program irq code 0x%x", irq->u.pgm.code);
trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_PROGRAM_INT, trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_PROGRAM_INT,
irq->u.pgm.code, 0); irq->u.pgm.code, 0);
...@@ -1309,6 +1313,7 @@ static int __inject_pfault_init(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq) ...@@ -1309,6 +1313,7 @@ static int __inject_pfault_init(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq)
{ {
struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
vcpu->stat.inject_pfault_init++;
VCPU_EVENT(vcpu, 4, "inject: pfault init parameter block at 0x%llx", VCPU_EVENT(vcpu, 4, "inject: pfault init parameter block at 0x%llx",
irq->u.ext.ext_params2); irq->u.ext.ext_params2);
trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_INT_PFAULT_INIT, trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_INT_PFAULT_INIT,
...@@ -1327,6 +1332,7 @@ static int __inject_extcall(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq) ...@@ -1327,6 +1332,7 @@ static int __inject_extcall(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq)
struct kvm_s390_extcall_info *extcall = &li->irq.extcall; struct kvm_s390_extcall_info *extcall = &li->irq.extcall;
uint16_t src_id = irq->u.extcall.code; uint16_t src_id = irq->u.extcall.code;
vcpu->stat.inject_external_call++;
VCPU_EVENT(vcpu, 4, "inject: external call source-cpu:%u", VCPU_EVENT(vcpu, 4, "inject: external call source-cpu:%u",
src_id); src_id);
trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_INT_EXTERNAL_CALL, trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_INT_EXTERNAL_CALL,
...@@ -1351,6 +1357,7 @@ static int __inject_set_prefix(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq) ...@@ -1351,6 +1357,7 @@ static int __inject_set_prefix(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq)
struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
struct kvm_s390_prefix_info *prefix = &li->irq.prefix; struct kvm_s390_prefix_info *prefix = &li->irq.prefix;
vcpu->stat.inject_set_prefix++;
VCPU_EVENT(vcpu, 3, "inject: set prefix to %x", VCPU_EVENT(vcpu, 3, "inject: set prefix to %x",
irq->u.prefix.address); irq->u.prefix.address);
trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_SIGP_SET_PREFIX, trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_SIGP_SET_PREFIX,
...@@ -1371,6 +1378,7 @@ static int __inject_sigp_stop(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq) ...@@ -1371,6 +1378,7 @@ static int __inject_sigp_stop(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq)
struct kvm_s390_stop_info *stop = &li->irq.stop; struct kvm_s390_stop_info *stop = &li->irq.stop;
int rc = 0; int rc = 0;
vcpu->stat.inject_stop_signal++;
trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_SIGP_STOP, 0, 0); trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_SIGP_STOP, 0, 0);
if (irq->u.stop.flags & ~KVM_S390_STOP_SUPP_FLAGS) if (irq->u.stop.flags & ~KVM_S390_STOP_SUPP_FLAGS)
...@@ -1395,6 +1403,7 @@ static int __inject_sigp_restart(struct kvm_vcpu *vcpu, ...@@ -1395,6 +1403,7 @@ static int __inject_sigp_restart(struct kvm_vcpu *vcpu,
{ {
struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
vcpu->stat.inject_restart++;
VCPU_EVENT(vcpu, 3, "%s", "inject: restart int"); VCPU_EVENT(vcpu, 3, "%s", "inject: restart int");
trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_RESTART, 0, 0); trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_RESTART, 0, 0);
...@@ -1407,6 +1416,7 @@ static int __inject_sigp_emergency(struct kvm_vcpu *vcpu, ...@@ -1407,6 +1416,7 @@ static int __inject_sigp_emergency(struct kvm_vcpu *vcpu,
{ {
struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
vcpu->stat.inject_emergency_signal++;
VCPU_EVENT(vcpu, 4, "inject: emergency from cpu %u", VCPU_EVENT(vcpu, 4, "inject: emergency from cpu %u",
irq->u.emerg.code); irq->u.emerg.code);
trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_INT_EMERGENCY, trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_INT_EMERGENCY,
...@@ -1427,6 +1437,7 @@ static int __inject_mchk(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq) ...@@ -1427,6 +1437,7 @@ static int __inject_mchk(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq)
struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
struct kvm_s390_mchk_info *mchk = &li->irq.mchk; struct kvm_s390_mchk_info *mchk = &li->irq.mchk;
vcpu->stat.inject_mchk++;
VCPU_EVENT(vcpu, 3, "inject: machine check mcic 0x%llx", VCPU_EVENT(vcpu, 3, "inject: machine check mcic 0x%llx",
irq->u.mchk.mcic); irq->u.mchk.mcic);
trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_MCHK, 0, trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_MCHK, 0,
...@@ -1457,6 +1468,7 @@ static int __inject_ckc(struct kvm_vcpu *vcpu) ...@@ -1457,6 +1468,7 @@ static int __inject_ckc(struct kvm_vcpu *vcpu)
{ {
struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
vcpu->stat.inject_ckc++;
VCPU_EVENT(vcpu, 3, "%s", "inject: clock comparator external"); VCPU_EVENT(vcpu, 3, "%s", "inject: clock comparator external");
trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_INT_CLOCK_COMP, trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_INT_CLOCK_COMP,
0, 0); 0, 0);
...@@ -1470,6 +1482,7 @@ static int __inject_cpu_timer(struct kvm_vcpu *vcpu) ...@@ -1470,6 +1482,7 @@ static int __inject_cpu_timer(struct kvm_vcpu *vcpu)
{ {
struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
vcpu->stat.inject_cputm++;
VCPU_EVENT(vcpu, 3, "%s", "inject: cpu timer external"); VCPU_EVENT(vcpu, 3, "%s", "inject: cpu timer external");
trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_INT_CPU_TIMER, trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_INT_CPU_TIMER,
0, 0); 0, 0);
...@@ -1596,6 +1609,7 @@ static int __inject_service(struct kvm *kvm, ...@@ -1596,6 +1609,7 @@ static int __inject_service(struct kvm *kvm,
{ {
struct kvm_s390_float_interrupt *fi = &kvm->arch.float_int; struct kvm_s390_float_interrupt *fi = &kvm->arch.float_int;
kvm->stat.inject_service_signal++;
spin_lock(&fi->lock); spin_lock(&fi->lock);
fi->srv_signal.ext_params |= inti->ext.ext_params & SCCB_EVENT_PENDING; fi->srv_signal.ext_params |= inti->ext.ext_params & SCCB_EVENT_PENDING;
/* /*
...@@ -1621,6 +1635,7 @@ static int __inject_virtio(struct kvm *kvm, ...@@ -1621,6 +1635,7 @@ static int __inject_virtio(struct kvm *kvm,
{ {
struct kvm_s390_float_interrupt *fi = &kvm->arch.float_int; struct kvm_s390_float_interrupt *fi = &kvm->arch.float_int;
kvm->stat.inject_virtio++;
spin_lock(&fi->lock); spin_lock(&fi->lock);
if (fi->counters[FIRQ_CNTR_VIRTIO] >= KVM_S390_MAX_VIRTIO_IRQS) { if (fi->counters[FIRQ_CNTR_VIRTIO] >= KVM_S390_MAX_VIRTIO_IRQS) {
spin_unlock(&fi->lock); spin_unlock(&fi->lock);
...@@ -1638,6 +1653,7 @@ static int __inject_pfault_done(struct kvm *kvm, ...@@ -1638,6 +1653,7 @@ static int __inject_pfault_done(struct kvm *kvm,
{ {
struct kvm_s390_float_interrupt *fi = &kvm->arch.float_int; struct kvm_s390_float_interrupt *fi = &kvm->arch.float_int;
kvm->stat.inject_pfault_done++;
spin_lock(&fi->lock); spin_lock(&fi->lock);
if (fi->counters[FIRQ_CNTR_PFAULT] >= if (fi->counters[FIRQ_CNTR_PFAULT] >=
(ASYNC_PF_PER_VCPU * KVM_MAX_VCPUS)) { (ASYNC_PF_PER_VCPU * KVM_MAX_VCPUS)) {
...@@ -1657,6 +1673,7 @@ static int __inject_float_mchk(struct kvm *kvm, ...@@ -1657,6 +1673,7 @@ static int __inject_float_mchk(struct kvm *kvm,
{ {
struct kvm_s390_float_interrupt *fi = &kvm->arch.float_int; struct kvm_s390_float_interrupt *fi = &kvm->arch.float_int;
kvm->stat.inject_float_mchk++;
spin_lock(&fi->lock); spin_lock(&fi->lock);
fi->mchk.cr14 |= inti->mchk.cr14 & (1UL << CR_PENDING_SUBCLASS); fi->mchk.cr14 |= inti->mchk.cr14 & (1UL << CR_PENDING_SUBCLASS);
fi->mchk.mcic |= inti->mchk.mcic; fi->mchk.mcic |= inti->mchk.mcic;
...@@ -1672,6 +1689,7 @@ static int __inject_io(struct kvm *kvm, struct kvm_s390_interrupt_info *inti) ...@@ -1672,6 +1689,7 @@ static int __inject_io(struct kvm *kvm, struct kvm_s390_interrupt_info *inti)
struct list_head *list; struct list_head *list;
int isc; int isc;
kvm->stat.inject_io++;
isc = int_word_to_isc(inti->io.io_int_word); isc = int_word_to_isc(inti->io.io_int_word);
if (kvm->arch.gisa && inti->type & KVM_S390_INT_IO_AI_MASK) { if (kvm->arch.gisa && inti->type & KVM_S390_INT_IO_AI_MASK) {
......
...@@ -57,6 +57,7 @@ ...@@ -57,6 +57,7 @@
(KVM_MAX_VCPUS + LOCAL_IRQS)) (KVM_MAX_VCPUS + LOCAL_IRQS))
#define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU #define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU
#define VM_STAT(x) offsetof(struct kvm, stat.x), KVM_STAT_VM
struct kvm_stats_debugfs_item debugfs_entries[] = { struct kvm_stats_debugfs_item debugfs_entries[] = {
{ "userspace_handled", VCPU_STAT(exit_userspace) }, { "userspace_handled", VCPU_STAT(exit_userspace) },
...@@ -64,6 +65,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { ...@@ -64,6 +65,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
{ "exit_validity", VCPU_STAT(exit_validity) }, { "exit_validity", VCPU_STAT(exit_validity) },
{ "exit_stop_request", VCPU_STAT(exit_stop_request) }, { "exit_stop_request", VCPU_STAT(exit_stop_request) },
{ "exit_external_request", VCPU_STAT(exit_external_request) }, { "exit_external_request", VCPU_STAT(exit_external_request) },
{ "exit_io_request", VCPU_STAT(exit_io_request) },
{ "exit_external_interrupt", VCPU_STAT(exit_external_interrupt) }, { "exit_external_interrupt", VCPU_STAT(exit_external_interrupt) },
{ "exit_instruction", VCPU_STAT(exit_instruction) }, { "exit_instruction", VCPU_STAT(exit_instruction) },
{ "exit_pei", VCPU_STAT(exit_pei) }, { "exit_pei", VCPU_STAT(exit_pei) },
...@@ -78,15 +80,34 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { ...@@ -78,15 +80,34 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
{ "instruction_lctl", VCPU_STAT(instruction_lctl) }, { "instruction_lctl", VCPU_STAT(instruction_lctl) },
{ "instruction_stctl", VCPU_STAT(instruction_stctl) }, { "instruction_stctl", VCPU_STAT(instruction_stctl) },
{ "instruction_stctg", VCPU_STAT(instruction_stctg) }, { "instruction_stctg", VCPU_STAT(instruction_stctg) },
{ "deliver_ckc", VCPU_STAT(deliver_ckc) },
{ "deliver_cputm", VCPU_STAT(deliver_cputm) },
{ "deliver_emergency_signal", VCPU_STAT(deliver_emergency_signal) }, { "deliver_emergency_signal", VCPU_STAT(deliver_emergency_signal) },
{ "deliver_external_call", VCPU_STAT(deliver_external_call) }, { "deliver_external_call", VCPU_STAT(deliver_external_call) },
{ "deliver_service_signal", VCPU_STAT(deliver_service_signal) }, { "deliver_service_signal", VCPU_STAT(deliver_service_signal) },
{ "deliver_virtio_interrupt", VCPU_STAT(deliver_virtio_interrupt) }, { "deliver_virtio", VCPU_STAT(deliver_virtio) },
{ "deliver_stop_signal", VCPU_STAT(deliver_stop_signal) }, { "deliver_stop_signal", VCPU_STAT(deliver_stop_signal) },
{ "deliver_prefix_signal", VCPU_STAT(deliver_prefix_signal) }, { "deliver_prefix_signal", VCPU_STAT(deliver_prefix_signal) },
{ "deliver_restart_signal", VCPU_STAT(deliver_restart_signal) }, { "deliver_restart_signal", VCPU_STAT(deliver_restart_signal) },
{ "deliver_program_interruption", VCPU_STAT(deliver_program_int) }, { "deliver_program", VCPU_STAT(deliver_program) },
{ "deliver_io", VCPU_STAT(deliver_io) },
{ "deliver_machine_check", VCPU_STAT(deliver_machine_check) },
{ "exit_wait_state", VCPU_STAT(exit_wait_state) }, { "exit_wait_state", VCPU_STAT(exit_wait_state) },
{ "inject_ckc", VCPU_STAT(inject_ckc) },
{ "inject_cputm", VCPU_STAT(inject_cputm) },
{ "inject_external_call", VCPU_STAT(inject_external_call) },
{ "inject_float_mchk", VM_STAT(inject_float_mchk) },
{ "inject_emergency_signal", VCPU_STAT(inject_emergency_signal) },
{ "inject_io", VM_STAT(inject_io) },
{ "inject_mchk", VCPU_STAT(inject_mchk) },
{ "inject_pfault_done", VM_STAT(inject_pfault_done) },
{ "inject_program", VCPU_STAT(inject_program) },
{ "inject_restart", VCPU_STAT(inject_restart) },
{ "inject_service_signal", VM_STAT(inject_service_signal) },
{ "inject_set_prefix", VCPU_STAT(inject_set_prefix) },
{ "inject_stop_signal", VCPU_STAT(inject_stop_signal) },
{ "inject_pfault_init", VCPU_STAT(inject_pfault_init) },
{ "inject_virtio", VM_STAT(inject_virtio) },
{ "instruction_epsw", VCPU_STAT(instruction_epsw) }, { "instruction_epsw", VCPU_STAT(instruction_epsw) },
{ "instruction_gs", VCPU_STAT(instruction_gs) }, { "instruction_gs", VCPU_STAT(instruction_gs) },
{ "instruction_io_other", VCPU_STAT(instruction_io_other) }, { "instruction_io_other", VCPU_STAT(instruction_io_other) },
...@@ -151,13 +172,33 @@ static int nested; ...@@ -151,13 +172,33 @@ static int nested;
module_param(nested, int, S_IRUGO); module_param(nested, int, S_IRUGO);
MODULE_PARM_DESC(nested, "Nested virtualization support"); MODULE_PARM_DESC(nested, "Nested virtualization support");
/* upper facilities limit for kvm */
unsigned long kvm_s390_fac_list_mask[16] = { FACILITIES_KVM };
unsigned long kvm_s390_fac_list_mask_size(void) /*
* For now we handle at most 16 double words as this is what the s390 base
* kernel handles and stores in the prefix page. If we ever need to go beyond
* this, this requires changes to code, but the external uapi can stay.
*/
#define SIZE_INTERNAL 16
/*
* Base feature mask that defines default mask for facilities. Consists of the
* defines in FACILITIES_KVM and the non-hypervisor managed bits.
*/
static unsigned long kvm_s390_fac_base[SIZE_INTERNAL] = { FACILITIES_KVM };
/*
* Extended feature mask. Consists of the defines in FACILITIES_KVM_CPUMODEL
* and defines the facilities that can be enabled via a cpu model.
*/
static unsigned long kvm_s390_fac_ext[SIZE_INTERNAL] = { FACILITIES_KVM_CPUMODEL };
static unsigned long kvm_s390_fac_size(void)
{ {
BUILD_BUG_ON(ARRAY_SIZE(kvm_s390_fac_list_mask) > S390_ARCH_FAC_MASK_SIZE_U64); BUILD_BUG_ON(SIZE_INTERNAL > S390_ARCH_FAC_MASK_SIZE_U64);
return ARRAY_SIZE(kvm_s390_fac_list_mask); BUILD_BUG_ON(SIZE_INTERNAL > S390_ARCH_FAC_LIST_SIZE_U64);
BUILD_BUG_ON(SIZE_INTERNAL * sizeof(unsigned long) >
sizeof(S390_lowcore.stfle_fac_list));
return SIZE_INTERNAL;
} }
/* available cpu features supported by kvm */ /* available cpu features supported by kvm */
...@@ -678,6 +719,8 @@ static int kvm_s390_set_mem_control(struct kvm *kvm, struct kvm_device_attr *att ...@@ -678,6 +719,8 @@ static int kvm_s390_set_mem_control(struct kvm *kvm, struct kvm_device_attr *att
mutex_lock(&kvm->lock); mutex_lock(&kvm->lock);
if (!kvm->created_vcpus) { if (!kvm->created_vcpus) {
kvm->arch.use_cmma = 1; kvm->arch.use_cmma = 1;
/* Not compatible with cmma. */
kvm->arch.use_pfmfi = 0;
ret = 0; ret = 0;
} }
mutex_unlock(&kvm->lock); mutex_unlock(&kvm->lock);
...@@ -1582,7 +1625,7 @@ static int kvm_s390_get_cmma_bits(struct kvm *kvm, ...@@ -1582,7 +1625,7 @@ static int kvm_s390_get_cmma_bits(struct kvm *kvm,
return -EINVAL; return -EINVAL;
/* CMMA is disabled or was not used, or the buffer has length zero */ /* CMMA is disabled or was not used, or the buffer has length zero */
bufsize = min(args->count, KVM_S390_CMMA_SIZE_MAX); bufsize = min(args->count, KVM_S390_CMMA_SIZE_MAX);
if (!bufsize || !kvm->mm->context.use_cmma) { if (!bufsize || !kvm->mm->context.uses_cmm) {
memset(args, 0, sizeof(*args)); memset(args, 0, sizeof(*args));
return 0; return 0;
} }
...@@ -1659,7 +1702,7 @@ static int kvm_s390_get_cmma_bits(struct kvm *kvm, ...@@ -1659,7 +1702,7 @@ static int kvm_s390_get_cmma_bits(struct kvm *kvm,
/* /*
* This function sets the CMMA attributes for the given pages. If the input * This function sets the CMMA attributes for the given pages. If the input
* buffer has zero length, no action is taken, otherwise the attributes are * buffer has zero length, no action is taken, otherwise the attributes are
* set and the mm->context.use_cmma flag is set. * set and the mm->context.uses_cmm flag is set.
*/ */
static int kvm_s390_set_cmma_bits(struct kvm *kvm, static int kvm_s390_set_cmma_bits(struct kvm *kvm,
const struct kvm_s390_cmma_log *args) const struct kvm_s390_cmma_log *args)
...@@ -1709,9 +1752,9 @@ static int kvm_s390_set_cmma_bits(struct kvm *kvm, ...@@ -1709,9 +1752,9 @@ static int kvm_s390_set_cmma_bits(struct kvm *kvm,
srcu_read_unlock(&kvm->srcu, srcu_idx); srcu_read_unlock(&kvm->srcu, srcu_idx);
up_read(&kvm->mm->mmap_sem); up_read(&kvm->mm->mmap_sem);
if (!kvm->mm->context.use_cmma) { if (!kvm->mm->context.uses_cmm) {
down_write(&kvm->mm->mmap_sem); down_write(&kvm->mm->mmap_sem);
kvm->mm->context.use_cmma = 1; kvm->mm->context.uses_cmm = 1;
up_write(&kvm->mm->mmap_sem); up_write(&kvm->mm->mmap_sem);
} }
out: out:
...@@ -1966,20 +2009,15 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) ...@@ -1966,20 +2009,15 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
if (!kvm->arch.sie_page2) if (!kvm->arch.sie_page2)
goto out_err; goto out_err;
/* Populate the facility mask initially. */
memcpy(kvm->arch.model.fac_mask, S390_lowcore.stfle_fac_list,
sizeof(S390_lowcore.stfle_fac_list));
for (i = 0; i < S390_ARCH_FAC_LIST_SIZE_U64; i++) {
if (i < kvm_s390_fac_list_mask_size())
kvm->arch.model.fac_mask[i] &= kvm_s390_fac_list_mask[i];
else
kvm->arch.model.fac_mask[i] = 0UL;
}
/* Populate the facility list initially. */
kvm->arch.model.fac_list = kvm->arch.sie_page2->fac_list; kvm->arch.model.fac_list = kvm->arch.sie_page2->fac_list;
memcpy(kvm->arch.model.fac_list, kvm->arch.model.fac_mask,
S390_ARCH_FAC_LIST_SIZE_BYTE); for (i = 0; i < kvm_s390_fac_size(); i++) {
kvm->arch.model.fac_mask[i] = S390_lowcore.stfle_fac_list[i] &
(kvm_s390_fac_base[i] |
kvm_s390_fac_ext[i]);
kvm->arch.model.fac_list[i] = S390_lowcore.stfle_fac_list[i] &
kvm_s390_fac_base[i];
}
/* we are always in czam mode - even on pre z14 machines */ /* we are always in czam mode - even on pre z14 machines */
set_kvm_facility(kvm->arch.model.fac_mask, 138); set_kvm_facility(kvm->arch.model.fac_mask, 138);
...@@ -2027,6 +2065,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) ...@@ -2027,6 +2065,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
kvm->arch.css_support = 0; kvm->arch.css_support = 0;
kvm->arch.use_irqchip = 0; kvm->arch.use_irqchip = 0;
kvm->arch.use_pfmfi = sclp.has_pfmfi;
kvm->arch.epoch = 0; kvm->arch.epoch = 0;
spin_lock_init(&kvm->arch.start_stop_lock); spin_lock_init(&kvm->arch.start_stop_lock);
...@@ -2146,6 +2185,7 @@ static void sca_add_vcpu(struct kvm_vcpu *vcpu) ...@@ -2146,6 +2185,7 @@ static void sca_add_vcpu(struct kvm_vcpu *vcpu)
/* we still need the basic sca for the ipte control */ /* we still need the basic sca for the ipte control */
vcpu->arch.sie_block->scaoh = (__u32)(((__u64)sca) >> 32); vcpu->arch.sie_block->scaoh = (__u32)(((__u64)sca) >> 32);
vcpu->arch.sie_block->scaol = (__u32)(__u64)sca; vcpu->arch.sie_block->scaol = (__u32)(__u64)sca;
return;
} }
read_lock(&vcpu->kvm->arch.sca_lock); read_lock(&vcpu->kvm->arch.sca_lock);
if (vcpu->kvm->arch.use_esca) { if (vcpu->kvm->arch.use_esca) {
...@@ -2452,8 +2492,6 @@ int kvm_s390_vcpu_setup_cmma(struct kvm_vcpu *vcpu) ...@@ -2452,8 +2492,6 @@ int kvm_s390_vcpu_setup_cmma(struct kvm_vcpu *vcpu)
vcpu->arch.sie_block->cbrlo = get_zeroed_page(GFP_KERNEL); vcpu->arch.sie_block->cbrlo = get_zeroed_page(GFP_KERNEL);
if (!vcpu->arch.sie_block->cbrlo) if (!vcpu->arch.sie_block->cbrlo)
return -ENOMEM; return -ENOMEM;
vcpu->arch.sie_block->ecb2 &= ~ECB2_PFMFI;
return 0; return 0;
} }
...@@ -2489,7 +2527,7 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) ...@@ -2489,7 +2527,7 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
if (test_kvm_facility(vcpu->kvm, 73)) if (test_kvm_facility(vcpu->kvm, 73))
vcpu->arch.sie_block->ecb |= ECB_TE; vcpu->arch.sie_block->ecb |= ECB_TE;
if (test_kvm_facility(vcpu->kvm, 8) && sclp.has_pfmfi) if (test_kvm_facility(vcpu->kvm, 8) && vcpu->kvm->arch.use_pfmfi)
vcpu->arch.sie_block->ecb2 |= ECB2_PFMFI; vcpu->arch.sie_block->ecb2 |= ECB2_PFMFI;
if (test_kvm_facility(vcpu->kvm, 130)) if (test_kvm_facility(vcpu->kvm, 130))
vcpu->arch.sie_block->ecb2 |= ECB2_IEP; vcpu->arch.sie_block->ecb2 |= ECB2_IEP;
...@@ -3021,7 +3059,7 @@ static int kvm_s390_handle_requests(struct kvm_vcpu *vcpu) ...@@ -3021,7 +3059,7 @@ static int kvm_s390_handle_requests(struct kvm_vcpu *vcpu)
if (kvm_check_request(KVM_REQ_START_MIGRATION, vcpu)) { if (kvm_check_request(KVM_REQ_START_MIGRATION, vcpu)) {
/* /*
* Disable CMMA virtualization; we will emulate the ESSA * Disable CMM virtualization; we will emulate the ESSA
* instruction manually, in order to provide additional * instruction manually, in order to provide additional
* functionalities needed for live migration. * functionalities needed for live migration.
*/ */
...@@ -3031,11 +3069,11 @@ static int kvm_s390_handle_requests(struct kvm_vcpu *vcpu) ...@@ -3031,11 +3069,11 @@ static int kvm_s390_handle_requests(struct kvm_vcpu *vcpu)
if (kvm_check_request(KVM_REQ_STOP_MIGRATION, vcpu)) { if (kvm_check_request(KVM_REQ_STOP_MIGRATION, vcpu)) {
/* /*
* Re-enable CMMA virtualization if CMMA is available and * Re-enable CMM virtualization if CMMA is available and
* was used. * CMM has been used.
*/ */
if ((vcpu->kvm->arch.use_cmma) && if ((vcpu->kvm->arch.use_cmma) &&
(vcpu->kvm->mm->context.use_cmma)) (vcpu->kvm->mm->context.uses_cmm))
vcpu->arch.sie_block->ecb2 |= ECB2_CMMA; vcpu->arch.sie_block->ecb2 |= ECB2_CMMA;
goto retry; goto retry;
} }
...@@ -4042,7 +4080,7 @@ static int __init kvm_s390_init(void) ...@@ -4042,7 +4080,7 @@ static int __init kvm_s390_init(void)
} }
for (i = 0; i < 16; i++) for (i = 0; i < 16; i++)
kvm_s390_fac_list_mask[i] |= kvm_s390_fac_base[i] |=
S390_lowcore.stfle_fac_list[i] & nonhyp_mask(i); S390_lowcore.stfle_fac_list[i] & nonhyp_mask(i);
return kvm_init(NULL, sizeof(struct kvm_vcpu), 0, THIS_MODULE); return kvm_init(NULL, sizeof(struct kvm_vcpu), 0, THIS_MODULE);
......
...@@ -294,8 +294,6 @@ void exit_sie(struct kvm_vcpu *vcpu); ...@@ -294,8 +294,6 @@ void exit_sie(struct kvm_vcpu *vcpu);
void kvm_s390_sync_request(int req, struct kvm_vcpu *vcpu); void kvm_s390_sync_request(int req, struct kvm_vcpu *vcpu);
int kvm_s390_vcpu_setup_cmma(struct kvm_vcpu *vcpu); int kvm_s390_vcpu_setup_cmma(struct kvm_vcpu *vcpu);
void kvm_s390_vcpu_unsetup_cmma(struct kvm_vcpu *vcpu); void kvm_s390_vcpu_unsetup_cmma(struct kvm_vcpu *vcpu);
unsigned long kvm_s390_fac_list_mask_size(void);
extern unsigned long kvm_s390_fac_list_mask[];
void kvm_s390_set_cpu_timer(struct kvm_vcpu *vcpu, __u64 cputm); void kvm_s390_set_cpu_timer(struct kvm_vcpu *vcpu, __u64 cputm);
__u64 kvm_s390_get_cpu_timer(struct kvm_vcpu *vcpu); __u64 kvm_s390_get_cpu_timer(struct kvm_vcpu *vcpu);
......
...@@ -1078,9 +1078,9 @@ static int handle_essa(struct kvm_vcpu *vcpu) ...@@ -1078,9 +1078,9 @@ static int handle_essa(struct kvm_vcpu *vcpu)
* value really needs to be written to; if the value is * value really needs to be written to; if the value is
* already correct, we do nothing and avoid the lock. * already correct, we do nothing and avoid the lock.
*/ */
if (vcpu->kvm->mm->context.use_cmma == 0) { if (vcpu->kvm->mm->context.uses_cmm == 0) {
down_write(&vcpu->kvm->mm->mmap_sem); down_write(&vcpu->kvm->mm->mmap_sem);
vcpu->kvm->mm->context.use_cmma = 1; vcpu->kvm->mm->context.uses_cmm = 1;
up_write(&vcpu->kvm->mm->mmap_sem); up_write(&vcpu->kvm->mm->mmap_sem);
} }
/* /*
......
...@@ -62,6 +62,13 @@ static struct facility_def facility_defs[] = { ...@@ -62,6 +62,13 @@ static struct facility_def facility_defs[] = {
} }
}, },
{ {
/*
* FACILITIES_KVM contains the list of facilities that are part
* of the default facility mask and list that are passed to the
* initial CPU model. If no CPU model is used, this, together
* with the non-hypervisor managed bits, is the maximum list of
* guest facilities supported by KVM.
*/
.name = "FACILITIES_KVM", .name = "FACILITIES_KVM",
.bits = (int[]){ .bits = (int[]){
0, /* N3 instructions */ 0, /* N3 instructions */
...@@ -89,6 +96,19 @@ static struct facility_def facility_defs[] = { ...@@ -89,6 +96,19 @@ static struct facility_def facility_defs[] = {
-1 /* END */ -1 /* END */
} }
}, },
{
/*
* FACILITIES_KVM_CPUMODEL contains the list of facilities
* that can be enabled by CPU model code if the host supports
* it. These facilities are not passed to the guest without
* CPU model support.
*/
.name = "FACILITIES_KVM_CPUMODEL",
.bits = (int[]){
-1 /* END */
}
},
}; };
static void print_facility_list(struct facility_def *def) static void print_facility_list(struct facility_def *def)
......
...@@ -9,7 +9,9 @@ ...@@ -9,7 +9,9 @@
#include <linux/kbd_kern.h> #include <linux/kbd_kern.h>
#include <linux/kbd_diacr.h> #include <linux/kbd_diacr.h>
u_short plain_map[NR_KEYS] = { #include "keyboard.h"
u_short ebc_plain_map[NR_KEYS] = {
0xf000, 0xf000, 0xf000, 0xf000, 0xf000, 0xf000, 0xf000, 0xf000, 0xf000, 0xf000, 0xf000, 0xf000, 0xf000, 0xf000, 0xf000, 0xf000,
0xf000, 0xf000, 0xf000, 0xf000, 0xf000, 0xf000, 0xf000, 0xf000, 0xf000, 0xf000, 0xf000, 0xf000, 0xf000, 0xf000, 0xf000, 0xf000,
0xf000, 0xf000, 0xf000, 0xf000, 0xf000, 0xf000, 0xf000, 0xf000, 0xf000, 0xf000, 0xf000, 0xf000, 0xf000, 0xf000, 0xf000, 0xf000,
...@@ -85,12 +87,12 @@ static u_short shift_ctrl_map[NR_KEYS] = { ...@@ -85,12 +87,12 @@ static u_short shift_ctrl_map[NR_KEYS] = {
0xf20a, 0xf108, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf20a, 0xf108, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
}; };
ushort *key_maps[MAX_NR_KEYMAPS] = { ushort *ebc_key_maps[MAX_NR_KEYMAPS] = {
plain_map, shift_map, NULL, NULL, ebc_plain_map, shift_map, NULL, NULL,
ctrl_map, shift_ctrl_map, NULL, ctrl_map, shift_ctrl_map, NULL,
}; };
unsigned int keymap_count = 4; unsigned int ebc_keymap_count = 4;
/* /*
...@@ -99,7 +101,7 @@ unsigned int keymap_count = 4; ...@@ -99,7 +101,7 @@ unsigned int keymap_count = 4;
* the default and allocate dynamically in chunks of 512 bytes. * the default and allocate dynamically in chunks of 512 bytes.
*/ */
char func_buf[] = { char ebc_func_buf[] = {
'\033', '[', '[', 'A', 0, '\033', '[', '[', 'A', 0,
'\033', '[', '[', 'B', 0, '\033', '[', '[', 'B', 0,
'\033', '[', '[', 'C', 0, '\033', '[', '[', 'C', 0,
...@@ -123,37 +125,37 @@ char func_buf[] = { ...@@ -123,37 +125,37 @@ char func_buf[] = {
}; };
char *funcbufptr = func_buf; char *ebc_funcbufptr = ebc_func_buf;
int funcbufsize = sizeof(func_buf); int ebc_funcbufsize = sizeof(ebc_func_buf);
int funcbufleft = 0; /* space left */ int ebc_funcbufleft; /* space left */
char *func_table[MAX_NR_FUNC] = { char *ebc_func_table[MAX_NR_FUNC] = {
func_buf + 0, ebc_func_buf + 0,
func_buf + 5, ebc_func_buf + 5,
func_buf + 10, ebc_func_buf + 10,
func_buf + 15, ebc_func_buf + 15,
func_buf + 20, ebc_func_buf + 20,
func_buf + 25, ebc_func_buf + 25,
func_buf + 31, ebc_func_buf + 31,
func_buf + 37, ebc_func_buf + 37,
func_buf + 43, ebc_func_buf + 43,
func_buf + 49, ebc_func_buf + 49,
func_buf + 55, ebc_func_buf + 55,
func_buf + 61, ebc_func_buf + 61,
func_buf + 67, ebc_func_buf + 67,
func_buf + 73, ebc_func_buf + 73,
func_buf + 79, ebc_func_buf + 79,
func_buf + 85, ebc_func_buf + 85,
func_buf + 91, ebc_func_buf + 91,
func_buf + 97, ebc_func_buf + 97,
func_buf + 103, ebc_func_buf + 103,
func_buf + 109, ebc_func_buf + 109,
NULL, NULL,
}; };
struct kbdiacruc accent_table[MAX_DIACR] = { struct kbdiacruc ebc_accent_table[MAX_DIACR] = {
{'^', 'c', 0003}, {'^', 'd', 0004}, {'^', 'c', 0003}, {'^', 'd', 0004},
{'^', 'z', 0032}, {'^', 0012, 0000}, {'^', 'z', 0032}, {'^', 0012, 0000},
}; };
unsigned int accent_table_size = 4; unsigned int ebc_accent_table_size = 4;
...@@ -54,24 +54,24 @@ kbd_alloc(void) { ...@@ -54,24 +54,24 @@ kbd_alloc(void) {
kbd = kzalloc(sizeof(struct kbd_data), GFP_KERNEL); kbd = kzalloc(sizeof(struct kbd_data), GFP_KERNEL);
if (!kbd) if (!kbd)
goto out; goto out;
kbd->key_maps = kzalloc(sizeof(key_maps), GFP_KERNEL); kbd->key_maps = kzalloc(sizeof(ebc_key_maps), GFP_KERNEL);
if (!kbd->key_maps) if (!kbd->key_maps)
goto out_kbd; goto out_kbd;
for (i = 0; i < ARRAY_SIZE(key_maps); i++) { for (i = 0; i < ARRAY_SIZE(ebc_key_maps); i++) {
if (key_maps[i]) { if (ebc_key_maps[i]) {
kbd->key_maps[i] = kmemdup(key_maps[i], kbd->key_maps[i] = kmemdup(ebc_key_maps[i],
sizeof(u_short) * NR_KEYS, sizeof(u_short) * NR_KEYS,
GFP_KERNEL); GFP_KERNEL);
if (!kbd->key_maps[i]) if (!kbd->key_maps[i])
goto out_maps; goto out_maps;
} }
} }
kbd->func_table = kzalloc(sizeof(func_table), GFP_KERNEL); kbd->func_table = kzalloc(sizeof(ebc_func_table), GFP_KERNEL);
if (!kbd->func_table) if (!kbd->func_table)
goto out_maps; goto out_maps;
for (i = 0; i < ARRAY_SIZE(func_table); i++) { for (i = 0; i < ARRAY_SIZE(ebc_func_table); i++) {
if (func_table[i]) { if (ebc_func_table[i]) {
kbd->func_table[i] = kstrdup(func_table[i], kbd->func_table[i] = kstrdup(ebc_func_table[i],
GFP_KERNEL); GFP_KERNEL);
if (!kbd->func_table[i]) if (!kbd->func_table[i])
goto out_func; goto out_func;
...@@ -81,22 +81,22 @@ kbd_alloc(void) { ...@@ -81,22 +81,22 @@ kbd_alloc(void) {
kzalloc(sizeof(fn_handler_fn *) * NR_FN_HANDLER, GFP_KERNEL); kzalloc(sizeof(fn_handler_fn *) * NR_FN_HANDLER, GFP_KERNEL);
if (!kbd->fn_handler) if (!kbd->fn_handler)
goto out_func; goto out_func;
kbd->accent_table = kmemdup(accent_table, kbd->accent_table = kmemdup(ebc_accent_table,
sizeof(struct kbdiacruc) * MAX_DIACR, sizeof(struct kbdiacruc) * MAX_DIACR,
GFP_KERNEL); GFP_KERNEL);
if (!kbd->accent_table) if (!kbd->accent_table)
goto out_fn_handler; goto out_fn_handler;
kbd->accent_table_size = accent_table_size; kbd->accent_table_size = ebc_accent_table_size;
return kbd; return kbd;
out_fn_handler: out_fn_handler:
kfree(kbd->fn_handler); kfree(kbd->fn_handler);
out_func: out_func:
for (i = 0; i < ARRAY_SIZE(func_table); i++) for (i = 0; i < ARRAY_SIZE(ebc_func_table); i++)
kfree(kbd->func_table[i]); kfree(kbd->func_table[i]);
kfree(kbd->func_table); kfree(kbd->func_table);
out_maps: out_maps:
for (i = 0; i < ARRAY_SIZE(key_maps); i++) for (i = 0; i < ARRAY_SIZE(ebc_key_maps); i++)
kfree(kbd->key_maps[i]); kfree(kbd->key_maps[i]);
kfree(kbd->key_maps); kfree(kbd->key_maps);
out_kbd: out_kbd:
...@@ -112,10 +112,10 @@ kbd_free(struct kbd_data *kbd) ...@@ -112,10 +112,10 @@ kbd_free(struct kbd_data *kbd)
kfree(kbd->accent_table); kfree(kbd->accent_table);
kfree(kbd->fn_handler); kfree(kbd->fn_handler);
for (i = 0; i < ARRAY_SIZE(func_table); i++) for (i = 0; i < ARRAY_SIZE(ebc_func_table); i++)
kfree(kbd->func_table[i]); kfree(kbd->func_table[i]);
kfree(kbd->func_table); kfree(kbd->func_table);
for (i = 0; i < ARRAY_SIZE(key_maps); i++) for (i = 0; i < ARRAY_SIZE(ebc_key_maps); i++)
kfree(kbd->key_maps[i]); kfree(kbd->key_maps[i]);
kfree(kbd->key_maps); kfree(kbd->key_maps);
kfree(kbd); kfree(kbd);
...@@ -131,7 +131,7 @@ kbd_ascebc(struct kbd_data *kbd, unsigned char *ascebc) ...@@ -131,7 +131,7 @@ kbd_ascebc(struct kbd_data *kbd, unsigned char *ascebc)
int i, j, k; int i, j, k;
memset(ascebc, 0x40, 256); memset(ascebc, 0x40, 256);
for (i = 0; i < ARRAY_SIZE(key_maps); i++) { for (i = 0; i < ARRAY_SIZE(ebc_key_maps); i++) {
keymap = kbd->key_maps[i]; keymap = kbd->key_maps[i];
if (!keymap) if (!keymap)
continue; continue;
...@@ -158,7 +158,7 @@ kbd_ebcasc(struct kbd_data *kbd, unsigned char *ebcasc) ...@@ -158,7 +158,7 @@ kbd_ebcasc(struct kbd_data *kbd, unsigned char *ebcasc)
int i, j, k; int i, j, k;
memset(ebcasc, ' ', 256); memset(ebcasc, ' ', 256);
for (i = 0; i < ARRAY_SIZE(key_maps); i++) { for (i = 0; i < ARRAY_SIZE(ebc_key_maps); i++) {
keymap = kbd->key_maps[i]; keymap = kbd->key_maps[i];
if (!keymap) if (!keymap)
continue; continue;
......
...@@ -14,6 +14,17 @@ ...@@ -14,6 +14,17 @@
struct kbd_data; struct kbd_data;
extern int ebc_funcbufsize, ebc_funcbufleft;
extern char *ebc_func_table[MAX_NR_FUNC];
extern char ebc_func_buf[];
extern char *ebc_funcbufptr;
extern unsigned int ebc_keymap_count;
extern struct kbdiacruc ebc_accent_table[];
extern unsigned int ebc_accent_table_size;
extern unsigned short *ebc_key_maps[MAX_NR_KEYMAPS];
extern unsigned short ebc_plain_map[NR_KEYS];
typedef void (fn_handler_fn)(struct kbd_data *); typedef void (fn_handler_fn)(struct kbd_data *);
/* /*
......
...@@ -11,7 +11,7 @@ if TTY ...@@ -11,7 +11,7 @@ if TTY
config VT config VT
bool "Virtual terminal" if EXPERT bool "Virtual terminal" if EXPERT
depends on !S390 && !UML depends on !UML
select INPUT select INPUT
default y default y
---help--- ---help---
......
...@@ -3,7 +3,8 @@ ...@@ -3,7 +3,8 @@
# #
menu "Graphics support" menu "Graphics support"
depends on HAS_IOMEM
if HAS_IOMEM
config HAVE_FB_ATMEL config HAVE_FB_ATMEL
bool bool
...@@ -36,6 +37,8 @@ config VIDEOMODE_HELPERS ...@@ -36,6 +37,8 @@ config VIDEOMODE_HELPERS
config HDMI config HDMI
bool bool
endif # HAS_IOMEM
if VT if VT
source "drivers/video/console/Kconfig" source "drivers/video/console/Kconfig"
endif endif
......
...@@ -9,7 +9,7 @@ config VGA_CONSOLE ...@@ -9,7 +9,7 @@ config VGA_CONSOLE
depends on !4xx && !PPC_8xx && !SPARC && !M68K && !PARISC && !FRV && \ depends on !4xx && !PPC_8xx && !SPARC && !M68K && !PARISC && !FRV && \
!SUPERH && !BLACKFIN && !AVR32 && !MN10300 && !CRIS && \ !SUPERH && !BLACKFIN && !AVR32 && !MN10300 && !CRIS && \
(!ARM || ARCH_FOOTBRIDGE || ARCH_INTEGRATOR || ARCH_NETWINDER) && \ (!ARM || ARCH_FOOTBRIDGE || ARCH_INTEGRATOR || ARCH_NETWINDER) && \
!ARM64 && !ARC && !MICROBLAZE && !OPENRISC !ARM64 && !ARC && !MICROBLAZE && !OPENRISC && HAS_IOMEM && !S390
default y default y
help help
Saying Y here will allow you to use Linux in text mode through a Saying Y here will allow you to use Linux in text mode through a
...@@ -85,7 +85,7 @@ config MDA_CONSOLE ...@@ -85,7 +85,7 @@ config MDA_CONSOLE
config SGI_NEWPORT_CONSOLE config SGI_NEWPORT_CONSOLE
tristate "SGI Newport Console support" tristate "SGI Newport Console support"
depends on SGI_IP22 depends on SGI_IP22 && HAS_IOMEM
select FONT_SUPPORT select FONT_SUPPORT
help help
Say Y here if you want the console on the Newport aka XL graphics Say Y here if you want the console on the Newport aka XL graphics
...@@ -153,7 +153,7 @@ config FRAMEBUFFER_CONSOLE_ROTATION ...@@ -153,7 +153,7 @@ config FRAMEBUFFER_CONSOLE_ROTATION
config STI_CONSOLE config STI_CONSOLE
bool "STI text console" bool "STI text console"
depends on PARISC depends on PARISC && HAS_IOMEM
select FONT_SUPPORT select FONT_SUPPORT
default y default y
help help
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment