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 -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQIcBAABAgAGBQJaqXZWAAoJEBF7vIC1phx87qIP/0Zr9yC8uhU2nqtNVXf9Ezhl x2Qh7Psk52LQEORcVHzbV5o5YIQrZxDraJ6DHLT6L6Qqpnk3SkUbtUAc+V3nHfFu iIOGQ8GgAsjY2E6A5xKp0JcuJB9/3S7C+CDYMUuFhKHSLNwQvZmRQjn2CILugxPU lHO3WpT3wrlVxiI/27uD3T3M+PNsyrMSeB75NBbnW5oTGB3/TNl2159aNdbuvl6C Kn74P5FrzgGhAPcmIZkQHt6e8RLi1UBoMO/LC6+u0WFMH9E7GriiMt0bSxlsWdt8 7wCmQ5Pvv6oZm/SNDgULWfbF1iRL06pMMzArjpnAGUcMKcdTnmzs0lBSYNmbDSh4 LTQ/LBFxhqf39Hn+D/QaPAJiL0wWIHo6tsRJ9JGDatWuU7vgyfMYTBJmvvK4cGIw 70iSeOer6TqwCcDIOcsQpbA58kVJcYP+FDKV8ADAj6cVfTD+s6npVB+JwDtX2KKJ d2t4GUsRmEJUvQjRHxYspSyYDVcPO7KDZ5TpVW5GHo1fbim1P1LO/ti6eo9u9c/T By+t+m3CAMubd+zVeB5uz64wdt8ZhgYTFdvYN4L2chh3JWs3wf7Lkeot4vJ7HgoE VWNHVxbYovPNMrUVYNzU6zSbDkQz9hvG5rK2mwv7jmxYGUmv/mItDiF7gFsiRWXg N63FBCebeaVlfEJniWRz =vw46 -----END PGP SIGNATURE----- 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
This commit is contained in:
Коммит
4956aa3b8b
|
@ -4555,3 +4555,33 @@ Parameters: none
|
|||
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
|
||||
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 {
|
|||
u64 exit_userspace;
|
||||
u64 exit_null;
|
||||
u64 exit_external_request;
|
||||
u64 exit_io_request;
|
||||
u64 exit_external_interrupt;
|
||||
u64 exit_stop_request;
|
||||
u64 exit_validity;
|
||||
|
@ -310,16 +311,29 @@ struct kvm_vcpu_stat {
|
|||
u64 exit_program_interruption;
|
||||
u64 exit_instr_and_program;
|
||||
u64 exit_operation_exception;
|
||||
u64 deliver_ckc;
|
||||
u64 deliver_cputm;
|
||||
u64 deliver_external_call;
|
||||
u64 deliver_emergency_signal;
|
||||
u64 deliver_service_signal;
|
||||
u64 deliver_virtio_interrupt;
|
||||
u64 deliver_virtio;
|
||||
u64 deliver_stop_signal;
|
||||
u64 deliver_prefix_signal;
|
||||
u64 deliver_restart_signal;
|
||||
u64 deliver_program_int;
|
||||
u64 deliver_io_int;
|
||||
u64 deliver_program;
|
||||
u64 deliver_io;
|
||||
u64 deliver_machine_check;
|
||||
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_gs;
|
||||
u64 instruction_io_other;
|
||||
|
@ -644,7 +658,12 @@ struct kvm_vcpu_arch {
|
|||
};
|
||||
|
||||
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 {
|
||||
|
@ -792,6 +811,7 @@ struct kvm_arch{
|
|||
int css_support;
|
||||
int use_irqchip;
|
||||
int use_cmma;
|
||||
int use_pfmfi;
|
||||
int user_cpu_state_ctrl;
|
||||
int user_sigp;
|
||||
int user_stsi;
|
||||
|
|
|
@ -22,8 +22,8 @@ typedef struct {
|
|||
unsigned int has_pgste:1;
|
||||
/* The mmu context uses storage keys. */
|
||||
unsigned int use_skey:1;
|
||||
/* The mmu context uses CMMA. */
|
||||
unsigned int use_cmma:1;
|
||||
/* The mmu context uses CMM. */
|
||||
unsigned int uses_cmm:1;
|
||||
} mm_context_t;
|
||||
|
||||
#define INIT_MM_CONTEXT(name) \
|
||||
|
|
|
@ -31,7 +31,7 @@ static inline int init_new_context(struct task_struct *tsk,
|
|||
(current->mm && current->mm->context.alloc_pgste);
|
||||
mm->context.has_pgste = 0;
|
||||
mm->context.use_skey = 0;
|
||||
mm->context.use_cmma = 0;
|
||||
mm->context.uses_cmm = 0;
|
||||
#endif
|
||||
switch (mm->context.asce_limit) {
|
||||
case _REGION2_SIZE:
|
||||
|
|
|
@ -221,6 +221,8 @@ static void __init conmode_default(void)
|
|||
SET_CONSOLE_SCLP;
|
||||
#endif
|
||||
}
|
||||
if (IS_ENABLED(CONFIG_VT) && IS_ENABLED(CONFIG_DUMMY_CONSOLE))
|
||||
conswitchp = &dummy_con;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CRASH_DUMP
|
||||
|
|
|
@ -1050,8 +1050,7 @@ shadow_r2t:
|
|||
rc = gmap_shadow_r2t(sg, saddr, rfte.val, *fake);
|
||||
if (rc)
|
||||
return rc;
|
||||
/* fallthrough */
|
||||
}
|
||||
} /* fallthrough */
|
||||
case ASCE_TYPE_REGION2: {
|
||||
union region2_table_entry rste;
|
||||
|
||||
|
@ -1077,8 +1076,7 @@ shadow_r3t:
|
|||
rc = gmap_shadow_r3t(sg, saddr, rste.val, *fake);
|
||||
if (rc)
|
||||
return rc;
|
||||
/* fallthrough */
|
||||
}
|
||||
} /* fallthrough */
|
||||
case ASCE_TYPE_REGION3: {
|
||||
union region3_table_entry rtte;
|
||||
|
||||
|
@ -1113,8 +1111,7 @@ shadow_sgt:
|
|||
rc = gmap_shadow_sgt(sg, saddr, rtte.val, *fake);
|
||||
if (rc)
|
||||
return rc;
|
||||
/* fallthrough */
|
||||
}
|
||||
} /* fallthrough */
|
||||
case ASCE_TYPE_SEGMENT: {
|
||||
union segment_table_entry ste;
|
||||
|
||||
|
|
|
@ -50,18 +50,6 @@ u8 kvm_s390_get_ilen(struct kvm_vcpu *vcpu)
|
|||
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)
|
||||
{
|
||||
struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
|
||||
|
@ -465,8 +453,11 @@ int kvm_handle_sie_intercept(struct kvm_vcpu *vcpu)
|
|||
|
||||
switch (vcpu->arch.sie_block->icptcode) {
|
||||
case ICPT_EXTREQ:
|
||||
vcpu->stat.exit_external_request++;
|
||||
return 0;
|
||||
case ICPT_IOREQ:
|
||||
return handle_noop(vcpu);
|
||||
vcpu->stat.exit_io_request++;
|
||||
return 0;
|
||||
case ICPT_INST:
|
||||
rc = handle_instruction(vcpu);
|
||||
break;
|
||||
|
|
|
@ -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;
|
||||
int rc;
|
||||
|
||||
vcpu->stat.deliver_cputm++;
|
||||
trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_INT_CPU_TIMER,
|
||||
0, 0);
|
||||
|
||||
|
@ -410,6 +411,7 @@ static int __must_check __deliver_ckc(struct kvm_vcpu *vcpu)
|
|||
struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
|
||||
int rc;
|
||||
|
||||
vcpu->stat.deliver_ckc++;
|
||||
trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_INT_CLOCK_COMP,
|
||||
0, 0);
|
||||
|
||||
|
@ -595,6 +597,7 @@ static int __must_check __deliver_machine_check(struct kvm_vcpu *vcpu)
|
|||
trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id,
|
||||
KVM_S390_MCHK,
|
||||
mchk.cr14, mchk.mcic);
|
||||
vcpu->stat.deliver_machine_check++;
|
||||
rc = __write_machine_check(vcpu, &mchk);
|
||||
}
|
||||
return rc;
|
||||
|
@ -710,7 +713,7 @@ static int __must_check __deliver_prog(struct kvm_vcpu *vcpu)
|
|||
ilen = pgm_info.flags & KVM_S390_PGM_FLAGS_ILC_MASK;
|
||||
VCPU_EVENT(vcpu, 3, "deliver: program irq code 0x%x, ilen:%d",
|
||||
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,
|
||||
pgm_info.code, 0);
|
||||
|
||||
|
@ -899,7 +902,7 @@ static int __must_check __deliver_virtio(struct kvm_vcpu *vcpu)
|
|||
VCPU_EVENT(vcpu, 4,
|
||||
"deliver: virtio parm: 0x%x,parm64: 0x%llx",
|
||||
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,
|
||||
inti->type,
|
||||
inti->ext.ext_params,
|
||||
|
@ -975,7 +978,7 @@ static int __must_check __deliver_io(struct kvm_vcpu *vcpu,
|
|||
inti->io.subchannel_id >> 1 & 0x3,
|
||||
inti->io.subchannel_nr);
|
||||
|
||||
vcpu->stat.deliver_io_int++;
|
||||
vcpu->stat.deliver_io++;
|
||||
trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id,
|
||||
inti->type,
|
||||
((__u32)inti->io.subchannel_id << 16) |
|
||||
|
@ -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);
|
||||
memset(&io, 0, sizeof(io));
|
||||
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,
|
||||
KVM_S390_INT_IO(1, 0, 0, 0),
|
||||
((__u32)io.subchannel_id << 16) |
|
||||
|
@ -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;
|
||||
|
||||
vcpu->stat.inject_program++;
|
||||
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,
|
||||
irq->u.pgm.code, 0);
|
||||
|
@ -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;
|
||||
|
||||
vcpu->stat.inject_pfault_init++;
|
||||
VCPU_EVENT(vcpu, 4, "inject: pfault init parameter block at 0x%llx",
|
||||
irq->u.ext.ext_params2);
|
||||
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)
|
|||
struct kvm_s390_extcall_info *extcall = &li->irq.extcall;
|
||||
uint16_t src_id = irq->u.extcall.code;
|
||||
|
||||
vcpu->stat.inject_external_call++;
|
||||
VCPU_EVENT(vcpu, 4, "inject: external call source-cpu:%u",
|
||||
src_id);
|
||||
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)
|
|||
struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
|
||||
struct kvm_s390_prefix_info *prefix = &li->irq.prefix;
|
||||
|
||||
vcpu->stat.inject_set_prefix++;
|
||||
VCPU_EVENT(vcpu, 3, "inject: set prefix to %x",
|
||||
irq->u.prefix.address);
|
||||
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)
|
|||
struct kvm_s390_stop_info *stop = &li->irq.stop;
|
||||
int rc = 0;
|
||||
|
||||
vcpu->stat.inject_stop_signal++;
|
||||
trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_SIGP_STOP, 0, 0);
|
||||
|
||||
if (irq->u.stop.flags & ~KVM_S390_STOP_SUPP_FLAGS)
|
||||
|
@ -1395,6 +1403,7 @@ static int __inject_sigp_restart(struct kvm_vcpu *vcpu,
|
|||
{
|
||||
struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
|
||||
|
||||
vcpu->stat.inject_restart++;
|
||||
VCPU_EVENT(vcpu, 3, "%s", "inject: restart int");
|
||||
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,
|
|||
{
|
||||
struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
|
||||
|
||||
vcpu->stat.inject_emergency_signal++;
|
||||
VCPU_EVENT(vcpu, 4, "inject: emergency from cpu %u",
|
||||
irq->u.emerg.code);
|
||||
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)
|
|||
struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
|
||||
struct kvm_s390_mchk_info *mchk = &li->irq.mchk;
|
||||
|
||||
vcpu->stat.inject_mchk++;
|
||||
VCPU_EVENT(vcpu, 3, "inject: machine check mcic 0x%llx",
|
||||
irq->u.mchk.mcic);
|
||||
trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_MCHK, 0,
|
||||
|
@ -1457,6 +1468,7 @@ static int __inject_ckc(struct kvm_vcpu *vcpu)
|
|||
{
|
||||
struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
|
||||
|
||||
vcpu->stat.inject_ckc++;
|
||||
VCPU_EVENT(vcpu, 3, "%s", "inject: clock comparator external");
|
||||
trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_INT_CLOCK_COMP,
|
||||
0, 0);
|
||||
|
@ -1470,6 +1482,7 @@ static int __inject_cpu_timer(struct kvm_vcpu *vcpu)
|
|||
{
|
||||
struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
|
||||
|
||||
vcpu->stat.inject_cputm++;
|
||||
VCPU_EVENT(vcpu, 3, "%s", "inject: cpu timer external");
|
||||
trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_INT_CPU_TIMER,
|
||||
0, 0);
|
||||
|
@ -1596,6 +1609,7 @@ static int __inject_service(struct kvm *kvm,
|
|||
{
|
||||
struct kvm_s390_float_interrupt *fi = &kvm->arch.float_int;
|
||||
|
||||
kvm->stat.inject_service_signal++;
|
||||
spin_lock(&fi->lock);
|
||||
fi->srv_signal.ext_params |= inti->ext.ext_params & SCCB_EVENT_PENDING;
|
||||
/*
|
||||
|
@ -1621,6 +1635,7 @@ static int __inject_virtio(struct kvm *kvm,
|
|||
{
|
||||
struct kvm_s390_float_interrupt *fi = &kvm->arch.float_int;
|
||||
|
||||
kvm->stat.inject_virtio++;
|
||||
spin_lock(&fi->lock);
|
||||
if (fi->counters[FIRQ_CNTR_VIRTIO] >= KVM_S390_MAX_VIRTIO_IRQS) {
|
||||
spin_unlock(&fi->lock);
|
||||
|
@ -1638,6 +1653,7 @@ static int __inject_pfault_done(struct kvm *kvm,
|
|||
{
|
||||
struct kvm_s390_float_interrupt *fi = &kvm->arch.float_int;
|
||||
|
||||
kvm->stat.inject_pfault_done++;
|
||||
spin_lock(&fi->lock);
|
||||
if (fi->counters[FIRQ_CNTR_PFAULT] >=
|
||||
(ASYNC_PF_PER_VCPU * KVM_MAX_VCPUS)) {
|
||||
|
@ -1657,6 +1673,7 @@ static int __inject_float_mchk(struct kvm *kvm,
|
|||
{
|
||||
struct kvm_s390_float_interrupt *fi = &kvm->arch.float_int;
|
||||
|
||||
kvm->stat.inject_float_mchk++;
|
||||
spin_lock(&fi->lock);
|
||||
fi->mchk.cr14 |= inti->mchk.cr14 & (1UL << CR_PENDING_SUBCLASS);
|
||||
fi->mchk.mcic |= inti->mchk.mcic;
|
||||
|
@ -1672,6 +1689,7 @@ static int __inject_io(struct kvm *kvm, struct kvm_s390_interrupt_info *inti)
|
|||
struct list_head *list;
|
||||
int isc;
|
||||
|
||||
kvm->stat.inject_io++;
|
||||
isc = int_word_to_isc(inti->io.io_int_word);
|
||||
|
||||
if (kvm->arch.gisa && inti->type & KVM_S390_INT_IO_AI_MASK) {
|
||||
|
|
|
@ -57,6 +57,7 @@
|
|||
(KVM_MAX_VCPUS + LOCAL_IRQS))
|
||||
|
||||
#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[] = {
|
||||
{ "userspace_handled", VCPU_STAT(exit_userspace) },
|
||||
|
@ -64,6 +65,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
|
|||
{ "exit_validity", VCPU_STAT(exit_validity) },
|
||||
{ "exit_stop_request", VCPU_STAT(exit_stop_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_instruction", VCPU_STAT(exit_instruction) },
|
||||
{ "exit_pei", VCPU_STAT(exit_pei) },
|
||||
|
@ -78,15 +80,34 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
|
|||
{ "instruction_lctl", VCPU_STAT(instruction_lctl) },
|
||||
{ "instruction_stctl", VCPU_STAT(instruction_stctl) },
|
||||
{ "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_external_call", VCPU_STAT(deliver_external_call) },
|
||||
{ "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_prefix_signal", VCPU_STAT(deliver_prefix_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) },
|
||||
{ "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_gs", VCPU_STAT(instruction_gs) },
|
||||
{ "instruction_io_other", VCPU_STAT(instruction_io_other) },
|
||||
|
@ -151,13 +172,33 @@ static int nested;
|
|||
module_param(nested, int, S_IRUGO);
|
||||
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);
|
||||
return ARRAY_SIZE(kvm_s390_fac_list_mask);
|
||||
BUILD_BUG_ON(SIZE_INTERNAL > S390_ARCH_FAC_MASK_SIZE_U64);
|
||||
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 */
|
||||
|
@ -678,6 +719,8 @@ static int kvm_s390_set_mem_control(struct kvm *kvm, struct kvm_device_attr *att
|
|||
mutex_lock(&kvm->lock);
|
||||
if (!kvm->created_vcpus) {
|
||||
kvm->arch.use_cmma = 1;
|
||||
/* Not compatible with cmma. */
|
||||
kvm->arch.use_pfmfi = 0;
|
||||
ret = 0;
|
||||
}
|
||||
mutex_unlock(&kvm->lock);
|
||||
|
@ -1582,7 +1625,7 @@ static int kvm_s390_get_cmma_bits(struct kvm *kvm,
|
|||
return -EINVAL;
|
||||
/* CMMA is disabled or was not used, or the buffer has length zero */
|
||||
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));
|
||||
return 0;
|
||||
}
|
||||
|
@ -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
|
||||
* 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,
|
||||
const struct kvm_s390_cmma_log *args)
|
||||
|
@ -1709,9 +1752,9 @@ static int kvm_s390_set_cmma_bits(struct kvm *kvm,
|
|||
srcu_read_unlock(&kvm->srcu, srcu_idx);
|
||||
up_read(&kvm->mm->mmap_sem);
|
||||
|
||||
if (!kvm->mm->context.use_cmma) {
|
||||
if (!kvm->mm->context.uses_cmm) {
|
||||
down_write(&kvm->mm->mmap_sem);
|
||||
kvm->mm->context.use_cmma = 1;
|
||||
kvm->mm->context.uses_cmm = 1;
|
||||
up_write(&kvm->mm->mmap_sem);
|
||||
}
|
||||
out:
|
||||
|
@ -1966,20 +2009,15 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
|
|||
if (!kvm->arch.sie_page2)
|
||||
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;
|
||||
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 */
|
||||
set_kvm_facility(kvm->arch.model.fac_mask, 138);
|
||||
|
@ -2027,6 +2065,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
|
|||
|
||||
kvm->arch.css_support = 0;
|
||||
kvm->arch.use_irqchip = 0;
|
||||
kvm->arch.use_pfmfi = sclp.has_pfmfi;
|
||||
kvm->arch.epoch = 0;
|
||||
|
||||
spin_lock_init(&kvm->arch.start_stop_lock);
|
||||
|
@ -2146,6 +2185,7 @@ static void sca_add_vcpu(struct kvm_vcpu *vcpu)
|
|||
/* we still need the basic sca for the ipte control */
|
||||
vcpu->arch.sie_block->scaoh = (__u32)(((__u64)sca) >> 32);
|
||||
vcpu->arch.sie_block->scaol = (__u32)(__u64)sca;
|
||||
return;
|
||||
}
|
||||
read_lock(&vcpu->kvm->arch.sca_lock);
|
||||
if (vcpu->kvm->arch.use_esca) {
|
||||
|
@ -2452,8 +2492,6 @@ int kvm_s390_vcpu_setup_cmma(struct kvm_vcpu *vcpu)
|
|||
vcpu->arch.sie_block->cbrlo = get_zeroed_page(GFP_KERNEL);
|
||||
if (!vcpu->arch.sie_block->cbrlo)
|
||||
return -ENOMEM;
|
||||
|
||||
vcpu->arch.sie_block->ecb2 &= ~ECB2_PFMFI;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2489,7 +2527,7 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
|
|||
if (test_kvm_facility(vcpu->kvm, 73))
|
||||
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;
|
||||
if (test_kvm_facility(vcpu->kvm, 130))
|
||||
vcpu->arch.sie_block->ecb2 |= ECB2_IEP;
|
||||
|
@ -3021,7 +3059,7 @@ retry:
|
|||
|
||||
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
|
||||
* functionalities needed for live migration.
|
||||
*/
|
||||
|
@ -3031,11 +3069,11 @@ retry:
|
|||
|
||||
if (kvm_check_request(KVM_REQ_STOP_MIGRATION, vcpu)) {
|
||||
/*
|
||||
* Re-enable CMMA virtualization if CMMA is available and
|
||||
* was used.
|
||||
* Re-enable CMM virtualization if CMMA is available and
|
||||
* CMM has been used.
|
||||
*/
|
||||
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;
|
||||
goto retry;
|
||||
}
|
||||
|
@ -4042,7 +4080,7 @@ static int __init kvm_s390_init(void)
|
|||
}
|
||||
|
||||
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);
|
||||
|
||||
return kvm_init(NULL, sizeof(struct kvm_vcpu), 0, THIS_MODULE);
|
||||
|
|
|
@ -294,8 +294,6 @@ void exit_sie(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);
|
||||
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);
|
||||
__u64 kvm_s390_get_cpu_timer(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
|
||||
* 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);
|
||||
vcpu->kvm->mm->context.use_cmma = 1;
|
||||
vcpu->kvm->mm->context.uses_cmm = 1;
|
||||
up_write(&vcpu->kvm->mm->mmap_sem);
|
||||
}
|
||||
/*
|
||||
|
|
|
@ -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",
|
||||
.bits = (int[]){
|
||||
0, /* N3 instructions */
|
||||
|
@ -89,6 +96,19 @@ static struct facility_def facility_defs[] = {
|
|||
-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)
|
||||
|
|
|
@ -9,7 +9,9 @@
|
|||
#include <linux/kbd_kern.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,
|
||||
|
@ -85,12 +87,12 @@ static u_short shift_ctrl_map[NR_KEYS] = {
|
|||
0xf20a, 0xf108, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
};
|
||||
|
||||
ushort *key_maps[MAX_NR_KEYMAPS] = {
|
||||
plain_map, shift_map, NULL, NULL,
|
||||
ushort *ebc_key_maps[MAX_NR_KEYMAPS] = {
|
||||
ebc_plain_map, shift_map, NULL, 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;
|
|||
* the default and allocate dynamically in chunks of 512 bytes.
|
||||
*/
|
||||
|
||||
char func_buf[] = {
|
||||
char ebc_func_buf[] = {
|
||||
'\033', '[', '[', 'A', 0,
|
||||
'\033', '[', '[', 'B', 0,
|
||||
'\033', '[', '[', 'C', 0,
|
||||
|
@ -123,37 +125,37 @@ char func_buf[] = {
|
|||
};
|
||||
|
||||
|
||||
char *funcbufptr = func_buf;
|
||||
int funcbufsize = sizeof(func_buf);
|
||||
int funcbufleft = 0; /* space left */
|
||||
char *ebc_funcbufptr = ebc_func_buf;
|
||||
int ebc_funcbufsize = sizeof(ebc_func_buf);
|
||||
int ebc_funcbufleft; /* space left */
|
||||
|
||||
char *func_table[MAX_NR_FUNC] = {
|
||||
func_buf + 0,
|
||||
func_buf + 5,
|
||||
func_buf + 10,
|
||||
func_buf + 15,
|
||||
func_buf + 20,
|
||||
func_buf + 25,
|
||||
func_buf + 31,
|
||||
func_buf + 37,
|
||||
func_buf + 43,
|
||||
func_buf + 49,
|
||||
func_buf + 55,
|
||||
func_buf + 61,
|
||||
func_buf + 67,
|
||||
func_buf + 73,
|
||||
func_buf + 79,
|
||||
func_buf + 85,
|
||||
func_buf + 91,
|
||||
func_buf + 97,
|
||||
func_buf + 103,
|
||||
func_buf + 109,
|
||||
char *ebc_func_table[MAX_NR_FUNC] = {
|
||||
ebc_func_buf + 0,
|
||||
ebc_func_buf + 5,
|
||||
ebc_func_buf + 10,
|
||||
ebc_func_buf + 15,
|
||||
ebc_func_buf + 20,
|
||||
ebc_func_buf + 25,
|
||||
ebc_func_buf + 31,
|
||||
ebc_func_buf + 37,
|
||||
ebc_func_buf + 43,
|
||||
ebc_func_buf + 49,
|
||||
ebc_func_buf + 55,
|
||||
ebc_func_buf + 61,
|
||||
ebc_func_buf + 67,
|
||||
ebc_func_buf + 73,
|
||||
ebc_func_buf + 79,
|
||||
ebc_func_buf + 85,
|
||||
ebc_func_buf + 91,
|
||||
ebc_func_buf + 97,
|
||||
ebc_func_buf + 103,
|
||||
ebc_func_buf + 109,
|
||||
NULL,
|
||||
};
|
||||
|
||||
struct kbdiacruc accent_table[MAX_DIACR] = {
|
||||
struct kbdiacruc ebc_accent_table[MAX_DIACR] = {
|
||||
{'^', 'c', 0003}, {'^', 'd', 0004},
|
||||
{'^', 'z', 0032}, {'^', 0012, 0000},
|
||||
};
|
||||
|
||||
unsigned int accent_table_size = 4;
|
||||
unsigned int ebc_accent_table_size = 4;
|
||||
|
|
|
@ -54,24 +54,24 @@ kbd_alloc(void) {
|
|||
kbd = kzalloc(sizeof(struct kbd_data), GFP_KERNEL);
|
||||
if (!kbd)
|
||||
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)
|
||||
goto out_kbd;
|
||||
for (i = 0; i < ARRAY_SIZE(key_maps); i++) {
|
||||
if (key_maps[i]) {
|
||||
kbd->key_maps[i] = kmemdup(key_maps[i],
|
||||
for (i = 0; i < ARRAY_SIZE(ebc_key_maps); i++) {
|
||||
if (ebc_key_maps[i]) {
|
||||
kbd->key_maps[i] = kmemdup(ebc_key_maps[i],
|
||||
sizeof(u_short) * NR_KEYS,
|
||||
GFP_KERNEL);
|
||||
if (!kbd->key_maps[i])
|
||||
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)
|
||||
goto out_maps;
|
||||
for (i = 0; i < ARRAY_SIZE(func_table); i++) {
|
||||
if (func_table[i]) {
|
||||
kbd->func_table[i] = kstrdup(func_table[i],
|
||||
for (i = 0; i < ARRAY_SIZE(ebc_func_table); i++) {
|
||||
if (ebc_func_table[i]) {
|
||||
kbd->func_table[i] = kstrdup(ebc_func_table[i],
|
||||
GFP_KERNEL);
|
||||
if (!kbd->func_table[i])
|
||||
goto out_func;
|
||||
|
@ -81,22 +81,22 @@ kbd_alloc(void) {
|
|||
kzalloc(sizeof(fn_handler_fn *) * NR_FN_HANDLER, GFP_KERNEL);
|
||||
if (!kbd->fn_handler)
|
||||
goto out_func;
|
||||
kbd->accent_table = kmemdup(accent_table,
|
||||
kbd->accent_table = kmemdup(ebc_accent_table,
|
||||
sizeof(struct kbdiacruc) * MAX_DIACR,
|
||||
GFP_KERNEL);
|
||||
if (!kbd->accent_table)
|
||||
goto out_fn_handler;
|
||||
kbd->accent_table_size = accent_table_size;
|
||||
kbd->accent_table_size = ebc_accent_table_size;
|
||||
return kbd;
|
||||
|
||||
out_fn_handler:
|
||||
kfree(kbd->fn_handler);
|
||||
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);
|
||||
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);
|
||||
out_kbd:
|
||||
|
@ -112,10 +112,10 @@ kbd_free(struct kbd_data *kbd)
|
|||
|
||||
kfree(kbd->accent_table);
|
||||
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);
|
||||
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);
|
||||
kfree(kbd);
|
||||
|
@ -131,7 +131,7 @@ kbd_ascebc(struct kbd_data *kbd, unsigned char *ascebc)
|
|||
int i, j, k;
|
||||
|
||||
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];
|
||||
if (!keymap)
|
||||
continue;
|
||||
|
@ -158,7 +158,7 @@ kbd_ebcasc(struct kbd_data *kbd, unsigned char *ebcasc)
|
|||
int i, j, k;
|
||||
|
||||
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];
|
||||
if (!keymap)
|
||||
continue;
|
||||
|
|
|
@ -14,6 +14,17 @@
|
|||
|
||||
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 *);
|
||||
|
||||
/*
|
||||
|
|
|
@ -11,7 +11,7 @@ if TTY
|
|||
|
||||
config VT
|
||||
bool "Virtual terminal" if EXPERT
|
||||
depends on !S390 && !UML
|
||||
depends on !UML
|
||||
select INPUT
|
||||
default y
|
||||
---help---
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
#
|
||||
|
||||
menu "Graphics support"
|
||||
depends on HAS_IOMEM
|
||||
|
||||
if HAS_IOMEM
|
||||
|
||||
config HAVE_FB_ATMEL
|
||||
bool
|
||||
|
@ -36,6 +37,8 @@ config VIDEOMODE_HELPERS
|
|||
config HDMI
|
||||
bool
|
||||
|
||||
endif # HAS_IOMEM
|
||||
|
||||
if VT
|
||||
source "drivers/video/console/Kconfig"
|
||||
endif
|
||||
|
|
|
@ -9,7 +9,7 @@ config VGA_CONSOLE
|
|||
depends on !4xx && !PPC_8xx && !SPARC && !M68K && !PARISC && !FRV && \
|
||||
!SUPERH && !BLACKFIN && !AVR32 && !MN10300 && !CRIS && \
|
||||
(!ARM || ARCH_FOOTBRIDGE || ARCH_INTEGRATOR || ARCH_NETWINDER) && \
|
||||
!ARM64 && !ARC && !MICROBLAZE && !OPENRISC
|
||||
!ARM64 && !ARC && !MICROBLAZE && !OPENRISC && HAS_IOMEM && !S390
|
||||
default y
|
||||
help
|
||||
Saying Y here will allow you to use Linux in text mode through a
|
||||
|
@ -85,7 +85,7 @@ config MDA_CONSOLE
|
|||
|
||||
config SGI_NEWPORT_CONSOLE
|
||||
tristate "SGI Newport Console support"
|
||||
depends on SGI_IP22
|
||||
depends on SGI_IP22 && HAS_IOMEM
|
||||
select FONT_SUPPORT
|
||||
help
|
||||
Say Y here if you want the console on the Newport aka XL graphics
|
||||
|
@ -153,7 +153,7 @@ config FRAMEBUFFER_CONSOLE_ROTATION
|
|||
|
||||
config STI_CONSOLE
|
||||
bool "STI text console"
|
||||
depends on PARISC
|
||||
depends on PARISC && HAS_IOMEM
|
||||
select FONT_SUPPORT
|
||||
default y
|
||||
help
|
||||
|
|
Загрузка…
Ссылка в новой задаче