Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20171215-v2' into staging

s390x changes for 2.12:
- Lots of tcg improvements: ccw hotplug is now working and we can run
  a Linux kernel built for z12 under tcg
- zPCI improvements to get virtio-pci working
- get rid of the cssid restrictions for virtual and non-virtual channel
  devices
- we now support 8TB+ systems
- 2.12 compat machine
- fixes and cleanups

# gpg: Signature made Fri 15 Dec 2017 10:57:01 GMT
# gpg:                using RSA key 0xDECF6B93C6F02FAF
# gpg: Good signature from "Cornelia Huck <conny@cornelia-huck.de>"
# gpg:                 aka "Cornelia Huck <huckc@linux.vnet.ibm.com>"
# gpg:                 aka "Cornelia Huck <cornelia.huck@de.ibm.com>"
# gpg:                 aka "Cornelia Huck <cohuck@kernel.org>"
# gpg:                 aka "Cornelia Huck <cohuck@redhat.com>"
# Primary key fingerprint: C3D0 D66D C362 4FF6 A8C0  18CE DECF 6B93 C6F0 2FAF

* remotes/cohuck/tags/s390x-20171215-v2: (46 commits)
  s390-ccw-virtio: allow for systems larger that 7.999TB
  s390x: change the QEMU cpu model to a stripped down z12
  s390x/tcg: we already implement the Set-Program-Parameter facility
  s390x/tcg: implement extract-CPU-time facility
  s390x/tcg: Implement SIGNAL ADAPTER instruction
  s390x/tcg: Implement STORE CHANNEL PATH STATUS
  s390x/tcg: wire up SET CHANNEL MONITOR
  s390x/tcg: wire up SET ADDRESS LIMIT
  s390x/tcg: implement Interlocked-Access Facility 2
  s390x/tcg: ASI/ASGI/ALSI/ALSGI are atomic with Interlocked-acccess facility 1
  s390x/tcg: wire up STORE CHANNEL REPORT WORD
  s390x/tcg: indicate value of TODPR in STCKE
  s390x/tcg: implement SET CLOCK PROGRAMMABLE FIELD
  s390x/tcg: fix and cleanup mcck injection
  s390x/kvm: factor out build_channel_report_mcic() into cpu.h
  s390x/css: attach css bridge
  s390x: deprecate s390-squash-mcss machine prop
  s390x/css: unrestrict cssids
  s390x/pci: search for subregion inside the BARs
  s390x/pci: move the memory region write from pcistg
  ...

# Conflicts:
#	include/hw/compat.h

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell
2017-12-15 12:58:17 +00:00
36 changed files with 928 additions and 547 deletions
+1 -1
View File
@@ -104,7 +104,7 @@ static void emulated_ccw_3270_realize(DeviceState *ds, Error **errp)
SubchDev *sch;
Error *err = NULL;
sch = css_create_sch(cdev->devno, true, cbus->squash_mcss, errp);
sch = css_create_sch(cdev->devno, cbus->squash_mcss, errp);
if (!sch) {
return;
}
+13
View File
@@ -99,6 +99,8 @@ VirtualCssBus *virtual_css_bus_init(void)
/* Create bridge device */
dev = qdev_create(NULL, TYPE_VIRTUAL_CSS_BRIDGE);
object_property_add_child(qdev_get_machine(), TYPE_VIRTUAL_CSS_BRIDGE,
OBJECT(dev), NULL);
qdev_init_nofail(dev);
/* Create bus on bridge device */
@@ -123,6 +125,11 @@ static Property virtual_css_bridge_properties[] = {
DEFINE_PROP_END_OF_LIST(),
};
static bool prop_get_true(Object *obj, Error **errp)
{
return true;
}
static void virtual_css_bridge_class_init(ObjectClass *klass, void *data)
{
HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);
@@ -131,6 +138,12 @@ static void virtual_css_bridge_class_init(ObjectClass *klass, void *data)
hc->unplug = ccw_device_unplug;
set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
dc->props = virtual_css_bridge_properties;
object_class_property_add_bool(klass, "cssid-unrestricted",
prop_get_true, NULL, NULL);
object_class_property_set_description(klass, "cssid-unrestricted",
"A css device can use any cssid, regardless whether virtual"
" or not (read only, always true)",
NULL);
}
static const TypeInfo virtual_css_bridge_info = {
+4 -30
View File
@@ -1723,12 +1723,6 @@ void css_undo_stcrw(CRW *crw)
QTAILQ_INSERT_HEAD(&channel_subsys.pending_crws, crw_cont, sibling);
}
int css_do_tpi(IOIntCode *int_code, int lowcore)
{
/* No pending interrupts for !KVM. */
return 0;
}
int css_collect_chp_desc(int m, uint8_t cssid, uint8_t f_chpid, uint8_t l_chpid,
int rfmt, void *buf)
{
@@ -2370,21 +2364,11 @@ const PropertyInfo css_devid_ro_propinfo = {
.get = get_css_devid,
};
SubchDev *css_create_sch(CssDevId bus_id, bool is_virtual, bool squash_mcss,
Error **errp)
SubchDev *css_create_sch(CssDevId bus_id, bool squash_mcss, Error **errp)
{
uint16_t schid = 0;
SubchDev *sch;
if (bus_id.valid) {
if (is_virtual != (bus_id.cssid == VIRTUAL_CSSID)) {
error_setg(errp, "cssid %hhx not valid for %s devices",
bus_id.cssid,
(is_virtual ? "virtual" : "non-virtual"));
return NULL;
}
}
if (bus_id.valid) {
if (squash_mcss) {
bus_id.cssid = channel_subsys.default_cssid;
@@ -2396,19 +2380,8 @@ SubchDev *css_create_sch(CssDevId bus_id, bool is_virtual, bool squash_mcss,
bus_id.devid, &schid, errp)) {
return NULL;
}
} else if (squash_mcss || is_virtual) {
bus_id.cssid = channel_subsys.default_cssid;
if (!css_find_free_subch_and_devno(bus_id.cssid, &bus_id.ssid,
&bus_id.devid, &schid, errp)) {
return NULL;
}
} else {
for (bus_id.cssid = 0; bus_id.cssid < MAX_CSSID; ++bus_id.cssid) {
if (bus_id.cssid == VIRTUAL_CSSID) {
continue;
}
for (bus_id.cssid = channel_subsys.default_cssid;;) {
if (!channel_subsys.css[bus_id.cssid]) {
css_create_css_image(bus_id.cssid, false);
}
@@ -2418,7 +2391,8 @@ SubchDev *css_create_sch(CssDevId bus_id, bool is_virtual, bool squash_mcss,
NULL)) {
break;
}
if (bus_id.cssid == MAX_CSSID) {
bus_id.cssid = (bus_id.cssid + 1) % MAX_CSSID;
if (bus_id.cssid == channel_subsys.default_cssid) {
error_setg(errp, "Virtual channel subsystem is full!");
return NULL;
}
+1 -1
View File
@@ -77,7 +77,7 @@ static void s390_ccw_realize(S390CCWDevice *cdev, char *sysfsdev, Error **errp)
goto out_err_propagate;
}
sch = css_create_sch(ccw_dev->devno, false, cbus->squash_mcss, &err);
sch = css_create_sch(ccw_dev->devno, cbus->squash_mcss, &err);
if (!sch) {
goto out_mdevid_free;
}
+1
View File
@@ -284,6 +284,7 @@ struct S390PCIBusDevice {
uint64_t fmb_addr;
uint8_t isc;
uint16_t noi;
uint16_t maxstbl;
uint8_t sum;
S390MsixInfo msix;
AdapterRoutes routes;
+200 -137
View File
File diff suppressed because it is too large Load Diff
+14 -8
View File
@@ -162,7 +162,7 @@ typedef struct ClpRspQueryPciGrp {
#define CLP_RSP_QPCIG_MASK_FRAME 0x2
#define CLP_RSP_QPCIG_MASK_REFRESH 0x1
uint8_t fr;
uint16_t reserved2;
uint16_t maxstbl;
uint16_t mui;
uint64_t reserved3;
uint64_t dasm; /* dma address space mask */
@@ -293,13 +293,19 @@ typedef struct ZpciFib {
int pci_dereg_irqs(S390PCIBusDevice *pbdev);
void pci_dereg_ioat(S390PCIIOMMU *iommu);
int clp_service_call(S390CPU *cpu, uint8_t r2);
int pcilg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2);
int pcistg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2);
int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2);
int clp_service_call(S390CPU *cpu, uint8_t r2, uintptr_t ra);
int pcilg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra);
int pcistg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra);
int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra);
int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t gaddr,
uint8_t ar);
int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar);
int stpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar);
uint8_t ar, uintptr_t ra);
int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar,
uintptr_t ra);
int stpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar,
uintptr_t ra);
#define ZPCI_IO_BAR_MIN 0
#define ZPCI_IO_BAR_MAX 5
#define ZPCI_CONFIG_BAR 15
#endif
+53 -6
View File
@@ -152,14 +152,38 @@ static void virtio_ccw_register_hcalls(void)
virtio_ccw_hcall_early_printk);
}
/*
* KVM does only support memory slots up to KVM_MEM_MAX_NR_PAGES pages
* as the dirty bitmap must be managed by bitops that take an int as
* position indicator. If we have a guest beyond that we will split off
* new subregions. The split must happen on a segment boundary (1MB).
*/
#define KVM_MEM_MAX_NR_PAGES ((1ULL << 31) - 1)
#define SEG_MSK (~0xfffffULL)
#define KVM_SLOT_MAX_BYTES ((KVM_MEM_MAX_NR_PAGES * TARGET_PAGE_SIZE) & SEG_MSK)
static void s390_memory_init(ram_addr_t mem_size)
{
MemoryRegion *sysmem = get_system_memory();
MemoryRegion *ram = g_new(MemoryRegion, 1);
ram_addr_t chunk, offset = 0;
unsigned int number = 0;
gchar *name;
/* allocate RAM for core */
memory_region_allocate_system_memory(ram, NULL, "s390.ram", mem_size);
memory_region_add_subregion(sysmem, 0, ram);
name = g_strdup_printf("s390.ram");
while (mem_size) {
MemoryRegion *ram = g_new(MemoryRegion, 1);
uint64_t size = mem_size;
/* KVM does not allow memslots >= 8 TB */
chunk = MIN(size, KVM_SLOT_MAX_BYTES);
memory_region_allocate_system_memory(ram, NULL, name, chunk);
memory_region_add_subregion(sysmem, offset, ram);
mem_size -= chunk;
offset += chunk;
g_free(name);
name = g_strdup_printf("s390.ram.%u", ++number);
}
g_free(name);
/* Initialize storage key device */
s390_skeys_init();
@@ -302,13 +326,17 @@ static void ccw_init(MachineState *machine)
/*
* Non mcss-e enabled guests only see the devices from the default
* css, which is determined by the value of the squash_mcss property.
* Note: we must not squash non virtual devices to css 0xFE.
*/
if (css_bus->squash_mcss) {
ret = css_create_css_image(0, true);
} else {
ret = css_create_css_image(VIRTUAL_CSSID, true);
}
if (qemu_opt_get(qemu_get_machine_opts(), "s390-squash-mcss")) {
warn_report("The machine property 's390-squash-mcss' is deprecated"
" (obsoleted by lifting the cssid restrictions).");
}
assert(ret == 0);
if (css_migration_enabled()) {
css_register_vmstate();
@@ -583,7 +611,7 @@ static inline void s390_machine_initfn(Object *obj)
object_property_add_bool(obj, "s390-squash-mcss",
machine_get_squash_mcss,
machine_set_squash_mcss, NULL);
object_property_set_description(obj, "s390-squash-mcss",
object_property_set_description(obj, "s390-squash-mcss", "(deprecated) "
"enable/disable squashing subchannels into the default css",
NULL);
object_property_set_bool(obj, false, "s390-squash-mcss", NULL);
@@ -639,6 +667,9 @@ bool css_migration_enabled(void)
} \
type_init(ccw_machine_register_##suffix)
#define CCW_COMPAT_2_11 \
HW_COMPAT_2_11
#define CCW_COMPAT_2_10 \
HW_COMPAT_2_10
@@ -716,14 +747,30 @@ bool css_migration_enabled(void)
.value = "0",\
},
static void ccw_machine_2_12_instance_options(MachineState *machine)
{
}
static void ccw_machine_2_12_class_options(MachineClass *mc)
{
}
DEFINE_CCW_MACHINE(2_12, "2.12", true);
static void ccw_machine_2_11_instance_options(MachineState *machine)
{
static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V2_11 };
ccw_machine_2_12_instance_options(machine);
/* before 2.12 we emulated the very first z900 */
s390_set_qemu_cpu_model(0x2064, 7, 1, qemu_cpu_feat);
}
static void ccw_machine_2_11_class_options(MachineClass *mc)
{
ccw_machine_2_12_class_options(mc);
SET_MACHINE_COMPAT(mc, CCW_COMPAT_2_11);
}
DEFINE_CCW_MACHINE(2_11, "2.11", true);
DEFINE_CCW_MACHINE(2_11, "2.11", false);
static void ccw_machine_2_10_instance_options(MachineState *machine)
{
+1 -1
View File
@@ -701,7 +701,7 @@ static void virtio_ccw_device_realize(VirtioCcwDevice *dev, Error **errp)
SubchDev *sch;
Error *err = NULL;
sch = css_create_sch(ccw_dev->devno, true, cbus->squash_mcss, errp);
sch = css_create_sch(ccw_dev->devno, cbus->squash_mcss, errp);
if (!sch) {
return;
}
+2 -1
View File
@@ -1,7 +1,8 @@
#ifndef HW_COMPAT_H
#define HW_COMPAT_H
#define HW_COMPAT_2_11
#define HW_COMPAT_2_11 \
/* empty */
#define HW_COMPAT_2_10 \
{\
+4 -9
View File
@@ -248,7 +248,6 @@ int css_do_tsch_get_irb(SubchDev *sch, IRB *irb, int *irb_len);
void css_do_tsch_update_subch(SubchDev *sch);
int css_do_stcrw(CRW *crw);
void css_undo_stcrw(CRW *crw);
int css_do_tpi(IOIntCode *int_code, int lowcore);
int css_collect_chp_desc(int m, uint8_t cssid, uint8_t f_chpid, uint8_t l_chpid,
int rfmt, void *buf);
void css_do_schm(uint8_t mbk, int update, int dct, uint64_t mbo);
@@ -272,12 +271,9 @@ extern const PropertyInfo css_devid_ro_propinfo;
* default css image for it.
* If @p bus_id is valid, and @p squash_mcss is false, verify that it is
* not already in use, and find a free devno for it.
* If @p bus_id is not valid, and if either @p squash_mcss or @p is_virtual
* is true, find a free subchannel id and device number across all
* subchannel sets from the default css image.
* If @p bus_id is not valid, and if both @p squash_mcss and @p is_virtual
* are false, find a non-full css image and find a free subchannel id and
* device number across all subchannel sets from it.
* If @p bus_id is not valid find a free subchannel id and device number
* across all subchannel sets and all css images starting from the default
* css image.
*
* If either of the former actions succeed, allocate a subchannel structure,
* initialise it with the bus id, subchannel id and device number, register
@@ -286,8 +282,7 @@ extern const PropertyInfo css_devid_ro_propinfo;
* The caller becomes owner of the returned subchannel structure and
* is responsible for unregistering and freeing it.
*/
SubchDev *css_create_sch(CssDevId bus_id, bool is_virtual, bool squash_mcss,
Error **errp);
SubchDev *css_create_sch(CssDevId bus_id, bool squash_mcss, Error **errp);
/** Turn on css migration */
void css_register_vmstate(void);
Binary file not shown.
+27 -3
View File
@@ -3,7 +3,7 @@
* into the pc-bios directory of qemu.
*
* Copyright (c) 2013 Alexander Graf <agraf@suse.de>
* Copyright 2013 IBM Corp.
* Copyright IBM Corp. 2013, 2017
*
* This work is licensed under the terms of the GNU GPL, version 2 or (at
* your option) any later version. See the COPYING file in the top-level
@@ -13,8 +13,32 @@
.globl _start
_start:
larl %r15, stack + 0x8000 /* Set up stack */
j main /* And call C */
larl %r15, stack + 0x8000 /* Set up stack */
/* clear bss */
larl %r2, __bss_start
larl %r3, _end
slgr %r3, %r2 /* get sizeof bss */
ltgr %r3,%r3 /* bss emtpy? */
jz done
aghi %r3,-1
srlg %r4,%r3,8 /* how many 256 byte chunks? */
ltgr %r4,%r4
lgr %r1,%r2
jz remainder
loop:
xc 0(256,%r1),0(%r1)
la %r1,256(%r1)
brctg %r4,loop
remainder:
larl %r2,memsetxc
ex %r3,0(%r2)
done:
j main /* And call C */
memsetxc:
xc 0(1,%r1),0(%r1)
/*
* void disabled_wait(void)
+8
View File
@@ -2501,6 +2501,14 @@ enabled via the ``-machine usb=on'' argument.
The ``-nodefconfig`` argument is a synonym for ``-no-user-config``.
@subsection -machine s390-squash-mcss=on|off (since 2.12.0)
The ``s390-squash-mcss=on`` property has been obsoleted by allowing the
cssid to be chosen freely. Instead of squashing subchannels into the
default channel subsystem image for guests that do not support multiple
channel subsystems, all devices can be put into the default channel
subsystem image.
@section qemu-img command line arguments
@subsection convert -s (since 2.0.0)
+7 -1
View File
@@ -43,7 +43,7 @@ DEF("machine", HAS_ARG, QEMU_OPTION_machine, \
" suppress-vmdesc=on|off disables self-describing migration (default=off)\n"
" nvdimm=on|off controls NVDIMM support (default=off)\n"
" enforce-config-section=on|off enforce configuration section migration (default=off)\n"
" s390-squash-mcss=on|off controls support for squashing into default css (default=off)\n",
" s390-squash-mcss=on|off (deprecated) controls support for squashing into default css (default=off)\n",
QEMU_ARCH_ALL)
STEXI
@item -machine [type=]@var{name}[,prop=@var{value}[,...]]
@@ -98,6 +98,12 @@ Enables or disables NVDIMM support. The default is off.
@item s390-squash-mcss=on|off
Enables or disables squashing subchannels into the default css.
The default is off.
NOTE: This property is deprecated and will be removed in future releases.
The ``s390-squash-mcss=on`` property has been obsoleted by allowing the
cssid to be chosen freely. Instead of squashing subchannels into the
default channel subsystem image for guests that do not support multiple
channel subsystems, all devices can be put into the default channel
subsystem image.
@item enforce-config-section=on|off
If @option{enforce-config-section} is set to @var{on}, force migration
code to send configuration section even if the machine-type sets the
+1 -1
View File
@@ -564,7 +564,7 @@ void HELPER(sacf)(CPUS390XState *env, uint64_t a1)
break;
default:
HELPER_LOG("unknown sacf mode: %" PRIx64 "\n", a1);
program_interrupt(env, PGM_SPECIFICATION, 2);
s390_program_interrupt(env, PGM_SPECIFICATION, 2, GETPC());
break;
}
}
+30 -1
View File
@@ -351,6 +351,9 @@ extern const struct VMStateDescription vmstate_s390_cpu;
#define CR0_CPU_TIMER_SC 0x0000000000000400ULL
#define CR0_SERVICE_SC 0x0000000000000200ULL
/* Control register 14 bits */
#define CR14_CHANNEL_REPORT_SC 0x0000000010000000ULL
/* MMU */
#define MMU_PRIMARY_IDX 0
#define MMU_SECONDARY_IDX 1
@@ -674,6 +677,26 @@ struct sysib_322 {
#define MCIC_VB_CT 0x0000000000020000ULL
#define MCIC_VB_CC 0x0000000000010000ULL
static inline uint64_t s390_build_validity_mcic(void)
{
uint64_t mcic;
/*
* Indicate all validity bits (no damage) only. Other bits have to be
* added by the caller. (storage errors, subclasses and subclass modifiers)
*/
mcic = MCIC_VB_WP | MCIC_VB_MS | MCIC_VB_PM | MCIC_VB_IA | MCIC_VB_FP |
MCIC_VB_GR | MCIC_VB_CR | MCIC_VB_ST | MCIC_VB_AR | MCIC_VB_PR |
MCIC_VB_FC | MCIC_VB_CT | MCIC_VB_CC;
if (s390_has_feat(S390_FEAT_VECTOR)) {
mcic |= MCIC_VB_VR;
}
if (s390_has_feat(S390_FEAT_GUARDED_STORAGE)) {
mcic |= MCIC_VB_GS;
}
return mcic;
}
/* cpu.c */
int s390_get_clock(uint8_t *tod_high, uint64_t *tod_low);
@@ -699,6 +722,9 @@ static inline unsigned int s390_cpu_set_state(uint8_t cpu_state, S390CPU *cpu)
/* cpu_models.c */
void s390_cpu_list(FILE *f, fprintf_function cpu_fprintf);
#define cpu_list s390_cpu_list
void s390_set_qemu_cpu_model(uint16_t type, uint8_t gen, uint8_t ec_ga,
const S390FeatInit feat_init);
/* helper.c */
#define cpu_init(cpu_model) cpu_generic_init(TYPE_S390_CPU, cpu_model)
@@ -719,7 +745,9 @@ void s390_io_interrupt(uint16_t subchannel_id, uint16_t subchannel_nr,
uint32_t io_int_parm, uint32_t io_int_word);
/* automatically detect the instruction length */
#define ILEN_AUTO 0xff
void program_interrupt(CPUS390XState *env, uint32_t code, int ilen);
#define RA_IGNORED 0
void s390_program_interrupt(CPUS390XState *env, uint32_t code, int ilen,
uintptr_t ra);
/* service interrupts are floating therefore we must not pass an cpustate */
void s390_sclp_extint(uint32_t parm);
@@ -733,6 +761,7 @@ int s390_cpu_virt_mem_rw(S390CPU *cpu, vaddr laddr, uint8_t ar, void *hostbuf,
s390_cpu_virt_mem_rw(cpu, laddr, ar, dest, len, true)
#define s390_cpu_virt_mem_check_write(cpu, laddr, ar, len) \
s390_cpu_virt_mem_rw(cpu, laddr, ar, NULL, len, true)
void s390_cpu_virt_mem_handle_exc(S390CPU *cpu, uintptr_t ra);
/* sigp.c */
+47 -56
View File
@@ -15,7 +15,6 @@
#include "internal.h"
#include "kvm_s390x.h"
#include "sysemu/kvm.h"
#include "gen-features.h"
#include "qapi/error.h"
#include "qapi/visitor.h"
#include "qemu/error-report.h"
@@ -81,6 +80,12 @@ static S390CPUDef s390_cpu_defs[] = {
CPUDEF_INIT(0x3906, 14, 1, 47, 0x08000000U, "z14", "IBM z14 GA1"),
};
#define QEMU_MAX_CPU_TYPE 0x2827
#define QEMU_MAX_CPU_GEN 12
#define QEMU_MAX_CPU_EC_GA 2
static const S390FeatInit qemu_max_cpu_feat_init = { S390_FEAT_LIST_QEMU_MAX };
static S390FeatBitmap qemu_max_cpu_feat;
/* features part of a base model but not relevant for finding a base model */
S390FeatBitmap ignored_base_feat;
@@ -812,48 +817,6 @@ static void check_compatibility(const S390CPUModel *max_model,
"available in the configuration: ");
}
/**
* The base TCG CPU model "qemu" is based on the z900. However, we already
* can also emulate some additional features of later CPU generations, so
* we add these additional feature bits here.
*/
static void add_qemu_cpu_model_features(S390FeatBitmap fbm)
{
static const int feats[] = {
S390_FEAT_DAT_ENH,
S390_FEAT_IDTE_SEGMENT,
S390_FEAT_STFLE,
S390_FEAT_SENSE_RUNNING_STATUS,
S390_FEAT_EXTENDED_IMMEDIATE,
S390_FEAT_EXTENDED_TRANSLATION_2,
S390_FEAT_MSA,
S390_FEAT_EXTENDED_TRANSLATION_3,
S390_FEAT_LONG_DISPLACEMENT,
S390_FEAT_LONG_DISPLACEMENT_FAST,
S390_FEAT_ETF2_ENH,
S390_FEAT_STORE_CLOCK_FAST,
S390_FEAT_MOVE_WITH_OPTIONAL_SPEC,
S390_FEAT_ETF3_ENH,
S390_FEAT_COMPARE_AND_SWAP_AND_STORE,
S390_FEAT_COMPARE_AND_SWAP_AND_STORE_2,
S390_FEAT_GENERAL_INSTRUCTIONS_EXT,
S390_FEAT_EXECUTE_EXT,
S390_FEAT_FLOATING_POINT_SUPPPORT_ENH,
S390_FEAT_STFLE_45,
S390_FEAT_STFLE_49,
S390_FEAT_LOCAL_TLB_CLEARING,
S390_FEAT_STFLE_53,
S390_FEAT_MSA_EXT_5,
S390_FEAT_MSA_EXT_3,
S390_FEAT_MSA_EXT_4,
};
int i;
for (i = 0; i < ARRAY_SIZE(feats); i++) {
set_bit(feats[i], fbm);
}
}
static S390CPUModel *get_max_cpu_model(Error **errp)
{
static S390CPUModel max_model;
@@ -866,12 +829,10 @@ static S390CPUModel *get_max_cpu_model(Error **errp)
if (kvm_enabled()) {
kvm_s390_get_host_cpu_model(&max_model, errp);
} else {
/* TCG emulates a z900 (with some optional additional features) */
max_model.def = &s390_cpu_defs[0];
bitmap_copy(max_model.features, max_model.def->default_feat,
S390_FEAT_MAX);
add_qemu_cpu_model_features(max_model.features);
}
max_model.def = s390_find_cpu_def(QEMU_MAX_CPU_TYPE, QEMU_MAX_CPU_GEN,
QEMU_MAX_CPU_EC_GA, NULL);
bitmap_copy(max_model.features, qemu_max_cpu_feat, S390_FEAT_MAX);
}
if (!*errp) {
cached = true;
return &max_model;
@@ -1127,18 +1088,42 @@ static void s390_host_cpu_model_initfn(Object *obj)
}
#endif
static S390CPUDef s390_qemu_cpu_def;
static S390CPUModel s390_qemu_cpu_model;
/* Set the qemu CPU model (on machine initialization). Must not be called
* once CPUs have been created.
*/
void s390_set_qemu_cpu_model(uint16_t type, uint8_t gen, uint8_t ec_ga,
const S390FeatInit feat_init)
{
const S390CPUDef *def = s390_find_cpu_def(type, gen, ec_ga, NULL);
g_assert(def);
g_assert(QTAILQ_EMPTY(&cpus));
/* TCG emulates some features that can usually not be enabled with
* the emulated machine generation. Make sure they can be enabled
* when using the QEMU model by adding them to full_feat. We have
* to copy the definition to do that.
*/
memcpy(&s390_qemu_cpu_def, def, sizeof(s390_qemu_cpu_def));
bitmap_or(s390_qemu_cpu_def.full_feat, s390_qemu_cpu_def.full_feat,
qemu_max_cpu_feat, S390_FEAT_MAX);
/* build the CPU model */
s390_qemu_cpu_model.def = &s390_qemu_cpu_def;
bitmap_zero(s390_qemu_cpu_model.features, S390_FEAT_MAX);
s390_init_feat_bitmap(feat_init, s390_qemu_cpu_model.features);
}
static void s390_qemu_cpu_model_initfn(Object *obj)
{
static S390CPUDef s390_qemu_cpu_defs;
S390CPU *cpu = S390_CPU(obj);
cpu->model = g_malloc0(sizeof(*cpu->model));
/* TCG emulates a z900 (with some optional additional features) */
memcpy(&s390_qemu_cpu_defs, &s390_cpu_defs[0], sizeof(s390_qemu_cpu_defs));
add_qemu_cpu_model_features(s390_qemu_cpu_defs.full_feat);
cpu->model->def = &s390_qemu_cpu_defs;
bitmap_copy(cpu->model->features, cpu->model->def->default_feat,
S390_FEAT_MAX);
/* copy the CPU model so we can modify it */
memcpy(cpu->model, &s390_qemu_cpu_model, sizeof(*cpu->model));
}
static void s390_cpu_model_finalize(Object *obj)
@@ -1279,11 +1264,13 @@ static void init_ignored_base_feat(void)
static void register_types(void)
{
static const S390FeatInit qemu_latest_init = { S390_FEAT_LIST_QEMU_LATEST };
int i;
init_ignored_base_feat();
/* init all bitmaps from gnerated data initially */
s390_init_feat_bitmap(qemu_max_cpu_feat_init, qemu_max_cpu_feat);
for (i = 0; i < ARRAY_SIZE(s390_cpu_defs); i++) {
s390_init_feat_bitmap(s390_cpu_defs[i].base_init,
s390_cpu_defs[i].base_feat);
@@ -1293,6 +1280,10 @@ static void register_types(void)
s390_cpu_defs[i].full_feat);
}
/* initialize the qemu model with latest definition */
s390_set_qemu_cpu_model(QEMU_MAX_CPU_TYPE, QEMU_MAX_CPU_GEN,
QEMU_MAX_CPU_EC_GA, qemu_latest_init);
for (i = 0; i < ARRAY_SIZE(s390_cpu_defs); i++) {
char *base_name = s390_base_cpu_type_name(s390_cpu_defs[i].name);
TypeInfo ti_base = {
+1
View File
@@ -14,6 +14,7 @@
#define TARGET_S390X_CPU_MODELS_H
#include "cpu_features.h"
#include "gen-features.h"
#include "qom/cpu.h"
/* static CPU definition */
+2 -5
View File
@@ -23,7 +23,6 @@ uint32_t HELPER(msa)(CPUS390XState *env, uint32_t r1, uint32_t r2, uint32_t r3,
const uintptr_t ra = GETPC();
const uint8_t mod = env->regs[0] & 0x80ULL;
const uint8_t fc = env->regs[0] & 0x7fULL;
CPUState *cs = CPU(s390_env_get_cpu(env));
uint8_t subfunc[16] = { 0 };
uint64_t param_addr;
int i;
@@ -35,8 +34,7 @@ uint32_t HELPER(msa)(CPUS390XState *env, uint32_t r1, uint32_t r2, uint32_t r3,
case S390_FEAT_TYPE_PCKMO:
case S390_FEAT_TYPE_PCC:
if (mod) {
cpu_restore_state(cs, ra);
program_interrupt(env, PGM_SPECIFICATION, 4);
s390_program_interrupt(env, PGM_SPECIFICATION, 4, ra);
return 0;
}
break;
@@ -44,8 +42,7 @@ uint32_t HELPER(msa)(CPUS390XState *env, uint32_t r1, uint32_t r2, uint32_t r3,
s390_get_feat_block(type, subfunc);
if (!test_be_bit(fc, subfunc)) {
cpu_restore_state(cs, ra);
program_interrupt(env, PGM_SPECIFICATION, 4);
s390_program_interrupt(env, PGM_SPECIFICATION, 4, ra);
return 0;
}

Some files were not shown because too many files have changed in this diff Show More