diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2015-03-16 11:44:55 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2015-03-16 11:44:55 +0000 |
commit | 2dfe7d07e2f40adb18a0b0cd286f3d327692d0fc (patch) | |
tree | 4790e055a2850435e3c8cf7dfdca5cd1d8b58708 /target-s390x | |
parent | f421f05754ac5aabe15f12051390204116408b00 (diff) | |
parent | be0b608a5463a834df0e19911356ae93660d3677 (diff) |
Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20150316' into staging
Final batch of s390x enhancements/fixes for 2.3:
- handle TOD clock during migration
- CPACF key wrap options
- limit amount of pci device code we build
- ensure big endian accesses for ccws
- various fixes and cleanups
# gpg: Signature made Mon Mar 16 10:01:44 2015 GMT using RSA key ID C6F02FAF
# gpg: Good signature from "Cornelia Huck <huckc@linux.vnet.ibm.com>"
# gpg: aka "Cornelia Huck <cornelia.huck@de.ibm.com>"
* remotes/cohuck/tags/s390x-20150316:
s390x/config: Do not include full pci.mak
s390x/pci: fix length in sei_nt2 event
s390x/ipl: remove dead code
s390x/virtio-bus: Remove unused function s390_virtio_bus_console()
s390x: CPACF: Handle key wrap machine options
s390x/kvm: make use of generic vm attribute check
kvm: encapsulate HAS_DEVICE for vm attrs
virtio-ccw: assure BE accesses
s390x/kvm: Guest Migration TOD clock synchronization
s390x: Replace unchecked qdev_init() by qdev_init_nofail()
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target-s390x')
-rw-r--r-- | target-s390x/cpu.h | 34 | ||||
-rw-r--r-- | target-s390x/kvm.c | 132 |
2 files changed, 131 insertions, 35 deletions
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h index 0171de0179..8135dda318 100644 --- a/target-s390x/cpu.h +++ b/target-s390x/cpu.h @@ -401,6 +401,8 @@ void kvm_s390_vcpu_interrupt(S390CPU *cpu, struct kvm_s390_irq *irq); void kvm_s390_floating_interrupt(struct kvm_s390_irq *irq); int kvm_s390_inject_flic(struct kvm_s390_irq *irq); void kvm_s390_access_exception(S390CPU *cpu, uint16_t code, uint64_t te_code); +int kvm_s390_get_clock(uint8_t *tod_high, uint64_t *tod_clock); +int kvm_s390_set_clock(uint8_t *tod_high, uint64_t *tod_clock); #else static inline void kvm_s390_virtio_irq(int config_change, uint64_t token) { @@ -408,11 +410,40 @@ static inline void kvm_s390_virtio_irq(int config_change, uint64_t token) static inline void kvm_s390_service_interrupt(uint32_t parm) { } +static inline int kvm_s390_get_clock(uint8_t *tod_high, uint64_t *tod_low) +{ + return -ENOSYS; +} +static inline int kvm_s390_set_clock(uint8_t *tod_high, uint64_t *tod_low) +{ + return -ENOSYS; +} static inline void kvm_s390_access_exception(S390CPU *cpu, uint16_t code, uint64_t te_code) { } #endif + +static inline int s390_get_clock(uint8_t *tod_high, uint64_t *tod_low) +{ + if (kvm_enabled()) { + return kvm_s390_get_clock(tod_high, tod_low); + } + /* Fixme TCG */ + *tod_high = 0; + *tod_low = 0; + return 0; +} + +static inline int s390_set_clock(uint8_t *tod_high, uint64_t *tod_low) +{ + if (kvm_enabled()) { + return kvm_s390_set_clock(tod_high, tod_low); + } + /* Fixme TCG */ + return 0; +} + S390CPU *s390_cpu_addr2state(uint16_t cpu_addr); unsigned int s390_cpu_halt(S390CPU *cpu); void s390_cpu_unhalt(S390CPU *cpu); @@ -422,6 +453,9 @@ static inline uint8_t s390_cpu_get_state(S390CPU *cpu) return cpu->env.cpu_state; } +void gtod_save(QEMUFile *f, void *opaque); +int gtod_load(QEMUFile *f, void *opaque, int version_id); + /* service interrupts are floating therefore we must not pass an cpustate */ void s390_sclp_extint(uint32_t parm); diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c index 896534bf95..b48c643b36 100644 --- a/target-s390x/kvm.c +++ b/target-s390x/kvm.c @@ -55,6 +55,9 @@ do { } while (0) #endif +#define kvm_vm_check_mem_attr(s, attr) \ + kvm_vm_check_attr(s, KVM_S390_VM_MEM_CTRL, attr) + #define IPA0_DIAG 0x8300 #define IPA0_SIGP 0xae00 #define IPA0_B2 0xb200 @@ -122,16 +125,6 @@ static int cap_async_pf; static void *legacy_s390_alloc(size_t size, uint64_t *align); -static int kvm_s390_supports_mem_limit(KVMState *s) -{ - struct kvm_device_attr attr = { - .group = KVM_S390_VM_MEM_CTRL, - .attr = KVM_S390_VM_MEM_LIMIT_SIZE, - }; - - return (kvm_vm_ioctl(s, KVM_HAS_DEVICE_ATTR, &attr) == 0); -} - static int kvm_s390_query_mem_limit(KVMState *s, uint64_t *memory_limit) { struct kvm_device_attr attr = { @@ -153,7 +146,7 @@ int kvm_s390_set_mem_limit(KVMState *s, uint64_t new_limit, uint64_t *hw_limit) .addr = (uint64_t) &new_limit, }; - if (!kvm_s390_supports_mem_limit(s)) { + if (!kvm_vm_check_mem_attr(s, KVM_S390_VM_MEM_LIMIT_SIZE)) { return 0; } @@ -167,26 +160,6 @@ int kvm_s390_set_mem_limit(KVMState *s, uint64_t new_limit, uint64_t *hw_limit) return kvm_vm_ioctl(s, KVM_SET_DEVICE_ATTR, &attr); } -static int kvm_s390_check_clear_cmma(KVMState *s) -{ - struct kvm_device_attr attr = { - .group = KVM_S390_VM_MEM_CTRL, - .attr = KVM_S390_VM_MEM_CLR_CMMA, - }; - - return kvm_vm_ioctl(s, KVM_HAS_DEVICE_ATTR, &attr); -} - -static int kvm_s390_check_enable_cmma(KVMState *s) -{ - struct kvm_device_attr attr = { - .group = KVM_S390_VM_MEM_CTRL, - .attr = KVM_S390_VM_MEM_ENABLE_CMMA, - }; - - return kvm_vm_ioctl(s, KVM_HAS_DEVICE_ATTR, &attr); -} - void kvm_s390_clear_cmma_callback(void *opaque) { int rc; @@ -208,7 +181,8 @@ static void kvm_s390_enable_cmma(KVMState *s) .attr = KVM_S390_VM_MEM_ENABLE_CMMA, }; - if (kvm_s390_check_enable_cmma(s) || kvm_s390_check_clear_cmma(s)) { + if (!kvm_vm_check_mem_attr(s, KVM_S390_VM_MEM_ENABLE_CMMA) || + !kvm_vm_check_mem_attr(s, KVM_S390_VM_MEM_CLR_CMMA)) { return; } @@ -219,14 +193,61 @@ static void kvm_s390_enable_cmma(KVMState *s) trace_kvm_enable_cmma(rc); } +static void kvm_s390_set_attr(uint64_t attr) +{ + struct kvm_device_attr attribute = { + .group = KVM_S390_VM_CRYPTO, + .attr = attr, + }; + + int ret = kvm_vm_ioctl(kvm_state, KVM_SET_DEVICE_ATTR, &attribute); + + if (ret) { + error_report("Failed to set crypto device attribute %lu: %s", + attr, strerror(-ret)); + } +} + +static void kvm_s390_init_aes_kw(void) +{ + uint64_t attr = KVM_S390_VM_CRYPTO_DISABLE_AES_KW; + + if (object_property_get_bool(OBJECT(qdev_get_machine()), "aes-key-wrap", + NULL)) { + attr = KVM_S390_VM_CRYPTO_ENABLE_AES_KW; + } + + if (kvm_vm_check_attr(kvm_state, KVM_S390_VM_CRYPTO, attr)) { + kvm_s390_set_attr(attr); + } +} + +static void kvm_s390_init_dea_kw(void) +{ + uint64_t attr = KVM_S390_VM_CRYPTO_DISABLE_DEA_KW; + + if (object_property_get_bool(OBJECT(qdev_get_machine()), "dea-key-wrap", + NULL)) { + attr = KVM_S390_VM_CRYPTO_ENABLE_DEA_KW; + } + + if (kvm_vm_check_attr(kvm_state, KVM_S390_VM_CRYPTO, attr)) { + kvm_s390_set_attr(attr); + } +} + +static void kvm_s390_init_crypto(void) +{ + kvm_s390_init_aes_kw(); + kvm_s390_init_dea_kw(); +} + int kvm_arch_init(MachineState *ms, KVMState *s) { cap_sync_regs = kvm_check_extension(s, KVM_CAP_SYNC_REGS); cap_async_pf = kvm_check_extension(s, KVM_CAP_ASYNC_PF); - if (kvm_check_extension(s, KVM_CAP_VM_ATTRIBUTES)) { - kvm_s390_enable_cmma(s); - } + kvm_s390_enable_cmma(s); if (!kvm_check_extension(s, KVM_CAP_S390_GMAP) || !kvm_check_extension(s, KVM_CAP_S390_COW)) { @@ -262,6 +283,8 @@ void kvm_s390_reset_vcpu(S390CPU *cpu) if (kvm_vcpu_ioctl(cs, KVM_S390_INITIAL_RESET, NULL)) { error_report("Initial CPU reset failed on CPU %i", cs->cpu_index); } + + kvm_s390_init_crypto(); } static int can_sync_regs(CPUState *cs, int regs) @@ -486,6 +509,45 @@ int kvm_arch_get_registers(CPUState *cs) return 0; } +int kvm_s390_get_clock(uint8_t *tod_high, uint64_t *tod_low) +{ + int r; + struct kvm_device_attr attr = { + .group = KVM_S390_VM_TOD, + .attr = KVM_S390_VM_TOD_LOW, + .addr = (uint64_t)tod_low, + }; + + r = kvm_vm_ioctl(kvm_state, KVM_GET_DEVICE_ATTR, &attr); + if (r) { + return r; + } + + attr.attr = KVM_S390_VM_TOD_HIGH; + attr.addr = (uint64_t)tod_high; + return kvm_vm_ioctl(kvm_state, KVM_GET_DEVICE_ATTR, &attr); +} + +int kvm_s390_set_clock(uint8_t *tod_high, uint64_t *tod_low) +{ + int r; + + struct kvm_device_attr attr = { + .group = KVM_S390_VM_TOD, + .attr = KVM_S390_VM_TOD_LOW, + .addr = (uint64_t)tod_low, + }; + + r = kvm_vm_ioctl(kvm_state, KVM_SET_DEVICE_ATTR, &attr); + if (r) { + return r; + } + + attr.attr = KVM_S390_VM_TOD_HIGH; + attr.addr = (uint64_t)tod_high; + return kvm_vm_ioctl(kvm_state, KVM_SET_DEVICE_ATTR, &attr); +} + /* * Legacy layout for s390: * Older S390 KVM requires the topmost vma of the RAM to be |