Skip to content

Commit

Permalink
hw/s390x/ioinst: Fix alignment problem in struct SubchDev
Browse files Browse the repository at this point in the history
struct SubchDev embeds several other structures which are marked with
QEMU_PACKED. This causes the compiler to not care for proper alignment
of these structures. When we later pass around pointers to the unaligned
struct members during migration, this causes problems on host architectures
like Sparc that can not do unaligned memory access.

Most of the structs in ioinst.h are naturally aligned, so we can fix
most of the problem by removing the QEMU_PACKED statements (and use
QEMU_BUILD_BUG_MSG() statements instead to make sure that there is no
padding). However, for the struct SCHIB, we have to keep the QEMU_PACKED
since the compiler adds some padding here otherwise. Move this struct
to the beginning of struct SubchDev instead to fix the alignment problem
here, too.

Signed-off-by: Thomas Huth <thuth@redhat.com>
Message-Id: <1538036615-32542-4-git-send-email-thuth@redhat.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
  • Loading branch information
huth authored and cohuck committed Oct 4, 2018
1 parent 729315e commit cb89b34
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 9 deletions.
4 changes: 2 additions & 2 deletions include/hw/s390x/css.h
Expand Up @@ -118,11 +118,12 @@ typedef enum IOInstEnding {
typedef struct SubchDev SubchDev;
struct SubchDev {
/* channel-subsystem related things: */
SCHIB curr_status; /* Needs alignment and thus must come first */
ORB orb;
uint8_t cssid;
uint8_t ssid;
uint16_t schid;
uint16_t devno;
SCHIB curr_status;
uint8_t sense_data[32];
hwaddr channel_prog;
CCW1 last_cmd;
Expand All @@ -131,7 +132,6 @@ struct SubchDev {
bool thinint_active;
uint8_t ccw_no_data_cnt;
uint16_t migrated_schid; /* used for missmatch detection */
ORB orb;
CcwDataStream cds;
/* transport-provided data: */
int (*ccw_cb) (SubchDev *, CCW1);
Expand Down
21 changes: 14 additions & 7 deletions include/hw/s390x/ioinst.h
Expand Up @@ -25,7 +25,8 @@ typedef struct SCSW {
uint8_t dstat;
uint8_t cstat;
uint16_t count;
} QEMU_PACKED SCSW;
} SCSW;
QEMU_BUILD_BUG_MSG(sizeof(SCSW) != 12, "size of SCSW is wrong");

#define SCSW_FLAGS_MASK_KEY 0xf000
#define SCSW_FLAGS_MASK_SCTL 0x0800
Expand Down Expand Up @@ -94,7 +95,8 @@ typedef struct PMCW {
uint8_t pam;
uint8_t chpid[8];
uint32_t chars;
} QEMU_PACKED PMCW;
} PMCW;
QEMU_BUILD_BUG_MSG(sizeof(PMCW) != 28, "size of PMCW is wrong");

#define PMCW_FLAGS_MASK_QF 0x8000
#define PMCW_FLAGS_MASK_W 0x4000
Expand Down Expand Up @@ -127,7 +129,8 @@ typedef struct IRB {
uint32_t esw[5];
uint32_t ecw[8];
uint32_t emw[8];
} QEMU_PACKED IRB;
} IRB;
QEMU_BUILD_BUG_MSG(sizeof(IRB) != 96, "size of IRB is wrong");

/* operation request block */
typedef struct ORB {
Expand All @@ -136,7 +139,8 @@ typedef struct ORB {
uint8_t lpm;
uint8_t ctrl1;
uint32_t cpa;
} QEMU_PACKED ORB;
} ORB;
QEMU_BUILD_BUG_MSG(sizeof(ORB) != 12, "size of ORB is wrong");

#define ORB_CTRL0_MASK_KEY 0xf000
#define ORB_CTRL0_MASK_SPND 0x0800
Expand Down Expand Up @@ -165,15 +169,17 @@ typedef struct CCW0 {
uint8_t flags;
uint8_t reserved;
uint16_t count;
} QEMU_PACKED CCW0;
} CCW0;
QEMU_BUILD_BUG_MSG(sizeof(CCW0) != 8, "size of CCW0 is wrong");

/* channel command word (type 1) */
typedef struct CCW1 {
uint8_t cmd_code;
uint8_t flags;
uint16_t count;
uint32_t cda;
} QEMU_PACKED CCW1;
} CCW1;
QEMU_BUILD_BUG_MSG(sizeof(CCW1) != 8, "size of CCW1 is wrong");

#define CCW_FLAG_DC 0x80
#define CCW_FLAG_CC 0x40
Expand All @@ -192,7 +198,8 @@ typedef struct CCW1 {
typedef struct CRW {
uint16_t flags;
uint16_t rsid;
} QEMU_PACKED CRW;
} CRW;
QEMU_BUILD_BUG_MSG(sizeof(CRW) != 4, "size of CRW is wrong");

#define CRW_FLAGS_MASK_S 0x4000
#define CRW_FLAGS_MASK_R 0x2000
Expand Down

0 comments on commit cb89b34

Please sign in to comment.