Skip to content

Commit

Permalink
Merge tag 'kvm-s390-next-20141128' of git://git.kernel.org/pub/scm/li…
Browse files Browse the repository at this point in the history
…nux/kernel/git/kvms390/linux into HEAD

KVM: s390: Several fixes,cleanups and reworks

Here is a bunch of fixes that deal mostly with architectural compliance:
- interrupt priorities
- interrupt handling
- intruction exit handling

We also provide a helper function for getting the guest visible storage key.
  • Loading branch information
Paolo Bonzini committed Dec 3, 2014
2 parents 2b4a273 + fc2020c commit be06b6b
Show file tree
Hide file tree
Showing 9 changed files with 872 additions and 399 deletions.
90 changes: 87 additions & 3 deletions arch/s390/include/asm/kvm_host.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ struct kvm_s390_sie_block {
#define ICPT_PARTEXEC 0x38
#define ICPT_IOINST 0x40
__u8 icptcode; /* 0x0050 */
__u8 reserved51; /* 0x0051 */
__u8 icptstatus; /* 0x0051 */
__u16 ihcpu; /* 0x0052 */
__u8 reserved54[2]; /* 0x0054 */
__u16 ipa; /* 0x0056 */
Expand Down Expand Up @@ -295,6 +295,79 @@ struct kvm_vcpu_stat {
#define PGM_PER 0x80
#define PGM_CRYPTO_OPERATION 0x119

/* irq types in order of priority */
enum irq_types {
IRQ_PEND_MCHK_EX = 0,
IRQ_PEND_SVC,
IRQ_PEND_PROG,
IRQ_PEND_MCHK_REP,
IRQ_PEND_EXT_IRQ_KEY,
IRQ_PEND_EXT_MALFUNC,
IRQ_PEND_EXT_EMERGENCY,
IRQ_PEND_EXT_EXTERNAL,
IRQ_PEND_EXT_CLOCK_COMP,
IRQ_PEND_EXT_CPU_TIMER,
IRQ_PEND_EXT_TIMING,
IRQ_PEND_EXT_SERVICE,
IRQ_PEND_EXT_HOST,
IRQ_PEND_PFAULT_INIT,
IRQ_PEND_PFAULT_DONE,
IRQ_PEND_VIRTIO,
IRQ_PEND_IO_ISC_0,
IRQ_PEND_IO_ISC_1,
IRQ_PEND_IO_ISC_2,
IRQ_PEND_IO_ISC_3,
IRQ_PEND_IO_ISC_4,
IRQ_PEND_IO_ISC_5,
IRQ_PEND_IO_ISC_6,
IRQ_PEND_IO_ISC_7,
IRQ_PEND_SIGP_STOP,
IRQ_PEND_RESTART,
IRQ_PEND_SET_PREFIX,
IRQ_PEND_COUNT
};

/*
* Repressible (non-floating) machine check interrupts
* subclass bits in MCIC
*/
#define MCHK_EXTD_BIT 58
#define MCHK_DEGR_BIT 56
#define MCHK_WARN_BIT 55
#define MCHK_REP_MASK ((1UL << MCHK_DEGR_BIT) | \
(1UL << MCHK_EXTD_BIT) | \
(1UL << MCHK_WARN_BIT))

/* Exigent machine check interrupts subclass bits in MCIC */
#define MCHK_SD_BIT 63
#define MCHK_PD_BIT 62
#define MCHK_EX_MASK ((1UL << MCHK_SD_BIT) | (1UL << MCHK_PD_BIT))

#define IRQ_PEND_EXT_MASK ((1UL << IRQ_PEND_EXT_IRQ_KEY) | \
(1UL << IRQ_PEND_EXT_CLOCK_COMP) | \
(1UL << IRQ_PEND_EXT_CPU_TIMER) | \
(1UL << IRQ_PEND_EXT_MALFUNC) | \
(1UL << IRQ_PEND_EXT_EMERGENCY) | \
(1UL << IRQ_PEND_EXT_EXTERNAL) | \
(1UL << IRQ_PEND_EXT_TIMING) | \
(1UL << IRQ_PEND_EXT_HOST) | \
(1UL << IRQ_PEND_EXT_SERVICE) | \
(1UL << IRQ_PEND_VIRTIO) | \
(1UL << IRQ_PEND_PFAULT_INIT) | \
(1UL << IRQ_PEND_PFAULT_DONE))

#define IRQ_PEND_IO_MASK ((1UL << IRQ_PEND_IO_ISC_0) | \
(1UL << IRQ_PEND_IO_ISC_1) | \
(1UL << IRQ_PEND_IO_ISC_2) | \
(1UL << IRQ_PEND_IO_ISC_3) | \
(1UL << IRQ_PEND_IO_ISC_4) | \
(1UL << IRQ_PEND_IO_ISC_5) | \
(1UL << IRQ_PEND_IO_ISC_6) | \
(1UL << IRQ_PEND_IO_ISC_7))

#define IRQ_PEND_MCHK_MASK ((1UL << IRQ_PEND_MCHK_REP) | \
(1UL << IRQ_PEND_MCHK_EX))

struct kvm_s390_interrupt_info {
struct list_head list;
u64 type;
Expand All @@ -313,14 +386,25 @@ struct kvm_s390_interrupt_info {
#define ACTION_STORE_ON_STOP (1<<0)
#define ACTION_STOP_ON_STOP (1<<1)

struct kvm_s390_irq_payload {
struct kvm_s390_io_info io;
struct kvm_s390_ext_info ext;
struct kvm_s390_pgm_info pgm;
struct kvm_s390_emerg_info emerg;
struct kvm_s390_extcall_info extcall;
struct kvm_s390_prefix_info prefix;
struct kvm_s390_mchk_info mchk;
};

struct kvm_s390_local_interrupt {
spinlock_t lock;
struct list_head list;
atomic_t active;
struct kvm_s390_float_interrupt *float_int;
wait_queue_head_t *wq;
atomic_t *cpuflags;
unsigned int action_bits;
DECLARE_BITMAP(sigp_emerg_pending, KVM_MAX_VCPUS);
struct kvm_s390_irq_payload irq;
unsigned long pending_irqs;
};

struct kvm_s390_float_interrupt {
Expand Down
1 change: 1 addition & 0 deletions arch/s390/include/asm/pgalloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ void page_table_reset_pgste(struct mm_struct *, unsigned long, unsigned long,
bool init_skey);
int set_guest_storage_key(struct mm_struct *mm, unsigned long addr,
unsigned long key, bool nq);
unsigned long get_guest_storage_key(struct mm_struct *mm, unsigned long addr);

static inline void clear_table(unsigned long *s, unsigned long val, size_t n)
{
Expand Down
20 changes: 16 additions & 4 deletions arch/s390/kvm/intercept.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,19 @@ static const intercept_handler_t instruction_handlers[256] = {
[0xeb] = kvm_s390_handle_eb,
};

void kvm_s390_rewind_psw(struct kvm_vcpu *vcpu, int ilc)
{
struct kvm_s390_sie_block *sie_block = vcpu->arch.sie_block;

/* Use the length of the EXECUTE instruction if necessary */
if (sie_block->icptstatus & 1) {
ilc = (sie_block->icptstatus >> 4) & 0x6;
if (!ilc)
ilc = 4;
}
sie_block->gpsw.addr = __rewind_psw(sie_block->gpsw, ilc);
}

static int handle_noop(struct kvm_vcpu *vcpu)
{
switch (vcpu->arch.sie_block->icptcode) {
Expand Down Expand Up @@ -244,7 +257,7 @@ static int handle_instruction_and_prog(struct kvm_vcpu *vcpu)
static int handle_external_interrupt(struct kvm_vcpu *vcpu)
{
u16 eic = vcpu->arch.sie_block->eic;
struct kvm_s390_interrupt irq;
struct kvm_s390_irq irq;
psw_t newpsw;
int rc;

Expand All @@ -269,7 +282,7 @@ static int handle_external_interrupt(struct kvm_vcpu *vcpu)
if (kvm_s390_si_ext_call_pending(vcpu))
return 0;
irq.type = KVM_S390_INT_EXTERNAL_CALL;
irq.parm = vcpu->arch.sie_block->extcpuaddr;
irq.u.extcall.code = vcpu->arch.sie_block->extcpuaddr;
break;
default:
return -EOPNOTSUPP;
Expand All @@ -288,7 +301,6 @@ static int handle_external_interrupt(struct kvm_vcpu *vcpu)
*/
static int handle_mvpg_pei(struct kvm_vcpu *vcpu)
{
psw_t *psw = &vcpu->arch.sie_block->gpsw;
unsigned long srcaddr, dstaddr;
int reg1, reg2, rc;

Expand All @@ -310,7 +322,7 @@ static int handle_mvpg_pei(struct kvm_vcpu *vcpu)
if (rc != 0)
return rc;

psw->addr = __rewind_psw(*psw, 4);
kvm_s390_rewind_psw(vcpu, 4);

return 0;
}
Expand Down
Loading

0 comments on commit be06b6b

Please sign in to comment.