From d524bcbb4437517a0f260af19f9d57bb81f53f8c Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Thu, 5 Mar 2020 17:53:38 +0000 Subject: [PATCH 01/19] Remove duplicate usr/libexec/cc1plus entry from ObsoleteFiles.inc. --- ObsoleteFiles.inc | 1 - 1 file changed, 1 deletion(-) diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc index 350b4696c22c..f49b799273fe 100644 --- a/ObsoleteFiles.inc +++ b/ObsoleteFiles.inc @@ -648,7 +648,6 @@ OLD_FILES+=usr/lib32/libsupc++.so OLD_LIBS+=usr/lib32/libsupc++.so.1 OLD_FILES+=usr/lib32/libsupc++_p.a .endif -OLD_FILES+=usr/libexec/cc1plus OLD_LIBS+=usr/lib/libgomp.so.1 OLD_FILES+=usr/lib/libgomp_p.a OLD_FILES+=usr/lib32/libgcov.a From 5c940cf1ff0c9ee98cd647814da76dd43df0e739 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Thu, 5 Mar 2020 19:43:43 +0000 Subject: [PATCH 02/19] Remove vfs.zfs.top_maxinflight tunable/sysctl. It is dead since sorted scrub import at r334844. MFC after: 1 week Sponsored by: iXsystems, Inc. --- .../contrib/opensolaris/uts/common/fs/zfs/dsl_scan.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_scan.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_scan.c index dee78d5971ed..8e73d388a945 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_scan.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_scan.c @@ -137,12 +137,6 @@ extern int zfs_vdev_async_write_active_min_dirty_percent; */ int zfs_scan_strict_mem_lim = B_FALSE; -/* - * Maximum number of parallelly executing I/Os per top-level vdev. - * Tune with care. Very high settings (hundreds) are known to trigger - * some firmware bugs and resets on certain SSDs. - */ -int zfs_top_maxinflight = 32; /* maximum I/Os per top-level */ unsigned int zfs_resilver_delay = 2; /* number of ticks to delay resilver -- 2 is a good number */ unsigned int zfs_scrub_delay = 4; /* number of ticks to delay scrub -- 4 is a good number */ unsigned int zfs_scan_idle = 50; /* idle window in clock ticks */ @@ -186,8 +180,6 @@ boolean_t zfs_no_scrub_io = B_FALSE; /* set to disable scrub i/o */ boolean_t zfs_no_scrub_prefetch = B_FALSE; /* set to disable scrub prefetch */ SYSCTL_DECL(_vfs_zfs); -SYSCTL_UINT(_vfs_zfs, OID_AUTO, top_maxinflight, CTLFLAG_RWTUN, - &zfs_top_maxinflight, 0, "Maximum I/Os per top-level vdev"); SYSCTL_UINT(_vfs_zfs, OID_AUTO, resilver_delay, CTLFLAG_RWTUN, &zfs_resilver_delay, 0, "Number of ticks to delay resilver"); SYSCTL_UINT(_vfs_zfs, OID_AUTO, scrub_delay, CTLFLAG_RWTUN, @@ -1538,7 +1530,6 @@ dsl_scan_prefetch_thread(void *arg) dsl_scan_t *scn = arg; spa_t *spa = scn->scn_dp->dp_spa; vdev_t *rvd = spa->spa_root_vdev; - uint64_t maxinflight = rvd->vdev_children * zfs_top_maxinflight; scan_prefetch_issue_ctx_t *spic; /* loop until we are told to stop */ From d8c51c6f74b61966ec57f498b3faf3ae93871918 Mon Sep 17 00:00:00 2001 From: Leandro Lupori Date: Thu, 5 Mar 2020 20:04:41 +0000 Subject: [PATCH 03/19] [aacraid] Port driver to big-endian Port aacraid driver to big-endian (BE) hosts. The immediate goal of this change is to make it possible to use the aacraid driver on PowerPC64 machines that have Adaptec Series 8 SAS controllers. Adapters supported by this driver expect FIB contents in little-endian (LE) byte order. All FIBs have a fixed header part as well as a data part that depends on the command being issued to the controller. In this way, on BE hosts, the FIB header and all FIB data structures used in aacraid.c and aacraid_cam.c need to be converted to LE before being sent to the adapter and converted to BE when coming from it. The functions to convert each struct are on aacraid_endian.c. For little-endian (LE) targets, they are macros that expand to nothing. In some cases, when only a few fields of a large structure are used, the fields are converted inline, by the code using them. PR: 237463 Reviewed by: jhibbits Sponsored by: Eldorado Research Institute (eldorado.org.br) Differential Revision: https://reviews.freebsd.org/D23887 --- sys/amd64/conf/NOTES | 4 - sys/conf/NOTES | 3 + sys/conf/files.powerpc | 1 + sys/dev/aacraid/aacraid.c | 100 ++++++-- sys/dev/aacraid/aacraid_cam.c | 15 +- sys/dev/aacraid/aacraid_endian.c | 389 +++++++++++++++++++++++++++++++ sys/dev/aacraid/aacraid_endian.h | 114 +++++++++ sys/modules/Makefile | 1 + sys/modules/aacraid/Makefile | 3 + sys/powerpc/conf/GENERIC64 | 1 + 10 files changed, 605 insertions(+), 26 deletions(-) create mode 100644 sys/dev/aacraid/aacraid_endian.c create mode 100644 sys/dev/aacraid/aacraid_endian.h diff --git a/sys/amd64/conf/NOTES b/sys/amd64/conf/NOTES index c24295629098..5d5b14d81c43 100644 --- a/sys/amd64/conf/NOTES +++ b/sys/amd64/conf/NOTES @@ -416,10 +416,6 @@ device twa # 3ware 9000 series PATA/SATA RAID device aac device aacp # SCSI Passthrough interface (optional, CAM required) -# -# Adaptec by PMC RAID controllers, Series 6/7/8 and upcoming families -device aacraid # Container interface, CAM required - # # Highpoint RocketRAID 27xx. device hpt27xx diff --git a/sys/conf/NOTES b/sys/conf/NOTES index d4a48f64ffa2..5f3a22088bc7 100644 --- a/sys/conf/NOTES +++ b/sys/conf/NOTES @@ -1490,6 +1490,8 @@ options TERMINAL_KERN_ATTR=(FG_LIGHTRED|BG_BLACK) # # SCSI host adapters: # +# aacraid: Adaptec by PMC RAID controllers, Series 6/7/8 and upcoming +# families. Container interface, CAM required. # ahc: Adaptec 274x/284x/2910/293x/294x/394x/3950x/3960x/398X/4944/ # 19160x/29160x, aic7770/aic78xx # ahd: Adaptec 29320/39320 Controllers. @@ -1512,6 +1514,7 @@ options TERMINAL_KERN_ATTR=(FG_LIGHTRED|BG_BLACK) # 53C876, 53C885, 53C895, 53C895A, 53C896, 53C897, 53C1510D, # 53C1010-33, 53C1010-66. +device aacraid device ahc device ahd device esp diff --git a/sys/conf/files.powerpc b/sys/conf/files.powerpc index e2136ee1416d..4013eae2836f 100644 --- a/sys/conf/files.powerpc +++ b/sys/conf/files.powerpc @@ -16,6 +16,7 @@ cddl/dev/dtrace/powerpc/dtrace_subr.c optional dtrace compile-with "${DTRACE_C} cddl/dev/fbt/powerpc/fbt_isa.c optional dtrace_fbt | dtraceall compile-with "${FBT_C}" crypto/blowfish/bf_enc.c optional crypto | ipsec | ipsec_support crypto/des/des_enc.c optional crypto | ipsec | ipsec_support | netsmb +dev/aacraid/aacraid_endian.c optional aacraid dev/adb/adb_bus.c optional adb dev/adb/adb_kbd.c optional adb dev/adb/adb_mouse.c optional adb diff --git a/sys/dev/aacraid/aacraid.c b/sys/dev/aacraid/aacraid.c index c8184fe5497b..cd7d27558e8a 100644 --- a/sys/dev/aacraid/aacraid.c +++ b/sys/dev/aacraid/aacraid.c @@ -69,6 +69,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #ifndef FILTER_HANDLED #define FILTER_HANDLED 0x02 @@ -386,7 +387,7 @@ aac_daemon(void *arg) AAC_FIBSTATE_ASYNC | AAC_FIBSTATE_FAST_RESPONSE; fib->Header.Command = SendHostTime; - *(uint32_t *)fib->data = tv.tv_sec; + *(uint32_t *)fib->data = htole32(tv.tv_sec); aacraid_map_command_sg(cm, NULL, 0, 0); aacraid_release_command(cm); @@ -446,6 +447,7 @@ aac_get_container_info(struct aac_softc *sc, struct aac_fib *sync_fib, int cid, mi->Command = VM_NameServe; mi->MntType = FT_FILESYS; mi->MntCount = cid; + aac_mntinfo_tole(mi); if (sync_fib) { if (aac_sync_fib(sc, ContainerCommand, 0, fib, @@ -476,6 +478,7 @@ aac_get_container_info(struct aac_softc *sc, struct aac_fib *sync_fib, int cid, } } bcopy(&fib->data[0], mir, sizeof(struct aac_mntinforesp)); + aac_mntinforesp_toh(mir); /* UID */ *uid = cid; @@ -490,10 +493,12 @@ aac_get_container_info(struct aac_softc *sc, struct aac_fib *sync_fib, int cid, ccfg->Command = VM_ContainerConfig; ccfg->CTCommand.command = CT_CID_TO_32BITS_UID; ccfg->CTCommand.param[0] = cid; + aac_cnt_config_tole(ccfg); if (sync_fib) { rval = aac_sync_fib(sc, ContainerCommand, 0, fib, sizeof(struct aac_cnt_config)); + aac_cnt_config_toh(ccfg); if (rval == 0 && ccfg->Command == ST_OK && ccfg->CTCommand.param[0] == CT_OK && mir->MntTable[0].VolType != CT_PASSTHRU) @@ -512,6 +517,7 @@ aac_get_container_info(struct aac_softc *sc, struct aac_fib *sync_fib, int cid, AAC_FIBSTATE_FAST_RESPONSE; fib->Header.Command = ContainerCommand; rval = aacraid_wait_command(cm); + aac_cnt_config_toh(ccfg); if (rval == 0 && ccfg->Command == ST_OK && ccfg->CTCommand.param[0] == CT_OK && mir->MntTable[0].VolType != CT_PASSTHRU) @@ -804,8 +810,8 @@ aacraid_shutdown(device_t dev) cc = (struct aac_close_command *)&fib->data[0]; bzero(cc, sizeof(struct aac_close_command)); - cc->Command = VM_CloseAll; - cc->ContainerId = 0xfffffffe; + cc->Command = htole32(VM_CloseAll); + cc->ContainerId = htole32(0xfffffffe); if (aac_sync_fib(sc, ContainerCommand, 0, fib, sizeof(struct aac_close_command))) printf("FAILED.\n"); @@ -905,6 +911,8 @@ aacraid_new_intr_type1(void *arg) cm = sc->aac_sync_cm; aac_unmap_command(cm); cm->cm_flags |= AAC_CMD_COMPLETED; + aac_fib_header_toh(&cm->cm_fib->Header); + /* is there a completion handler? */ if (cm->cm_complete != NULL) { cm->cm_complete(cm); @@ -931,7 +939,8 @@ aacraid_new_intr_type1(void *arg) for (;;) { isFastResponse = isAif = noMoreAif = 0; /* remove toggle bit (31) */ - handle = (sc->aac_common->ac_host_rrq[index] & 0x7fffffff); + handle = (le32toh(sc->aac_common->ac_host_rrq[index]) & + 0x7fffffff); /* check fast response bit (30) */ if (handle & 0x40000000) isFastResponse = 1; @@ -944,6 +953,7 @@ aacraid_new_intr_type1(void *arg) cm = sc->aac_commands + (handle - 1); fib = cm->cm_fib; + aac_fib_header_toh(&fib->Header); sc->aac_rrq_outstanding[vector_no]--; if (isAif) { noMoreAif = (fib->Header.XferState & AAC_FIBSTATE_NOMOREAIF) ? 1:0; @@ -954,7 +964,7 @@ aacraid_new_intr_type1(void *arg) } else { if (isFastResponse) { fib->Header.XferState |= AAC_FIBSTATE_DONEADAP; - *((u_int32_t *)(fib->data)) = ST_OK; + *((u_int32_t *)(fib->data)) = htole32(ST_OK); cm->cm_flags |= AAC_CMD_FASTRESP; } aac_remove_busy(cm); @@ -1342,6 +1352,10 @@ aacraid_map_command_sg(void *arg, bus_dma_segment_t *segs, int nseg, int error) raw->flags |= RIO2_SGL_CONFORMANT; } + for (i = 0; i < nseg; i++) + aac_sge_ieee1212_tole(sg + i); + aac_raw_io2_tole(raw); + /* update the FIB size for the s/g count */ fib->Header.Size += nseg * sizeof(struct aac_sge_ieee1212); @@ -1349,33 +1363,37 @@ aacraid_map_command_sg(void *arg, bus_dma_segment_t *segs, int nseg, int error) } else if (fib->Header.Command == RawIo) { struct aac_sg_tableraw *sg; sg = (struct aac_sg_tableraw *)cm->cm_sgtable; - sg->SgCount = nseg; + sg->SgCount = htole32(nseg); for (i = 0; i < nseg; i++) { sg->SgEntryRaw[i].SgAddress = segs[i].ds_addr; sg->SgEntryRaw[i].SgByteCount = segs[i].ds_len; sg->SgEntryRaw[i].Next = 0; sg->SgEntryRaw[i].Prev = 0; sg->SgEntryRaw[i].Flags = 0; + aac_sg_entryraw_tole(&sg->SgEntryRaw[i]); } + aac_raw_io_tole((struct aac_raw_io *)&fib->data[0]); /* update the FIB size for the s/g count */ fib->Header.Size += nseg*sizeof(struct aac_sg_entryraw); } else if ((cm->cm_sc->flags & AAC_FLAGS_SG_64BIT) == 0) { struct aac_sg_table *sg; sg = cm->cm_sgtable; - sg->SgCount = nseg; + sg->SgCount = htole32(nseg); for (i = 0; i < nseg; i++) { sg->SgEntry[i].SgAddress = segs[i].ds_addr; sg->SgEntry[i].SgByteCount = segs[i].ds_len; + aac_sg_entry_tole(&sg->SgEntry[i]); } /* update the FIB size for the s/g count */ fib->Header.Size += nseg*sizeof(struct aac_sg_entry); } else { struct aac_sg_table64 *sg; sg = (struct aac_sg_table64 *)cm->cm_sgtable; - sg->SgCount = nseg; + sg->SgCount = htole32(nseg); for (i = 0; i < nseg; i++) { sg->SgEntry64[i].SgAddress = segs[i].ds_addr; sg->SgEntry64[i].SgByteCount = segs[i].ds_len; + aac_sg_entry64_tole(&sg->SgEntry64[i]); } /* update the FIB size for the s/g count */ fib->Header.Size += nseg*sizeof(struct aac_sg_entry64); @@ -1405,11 +1423,13 @@ aacraid_map_command_sg(void *arg, bus_dma_segment_t *segs, int nseg, int error) cm->cm_flags |= AAC_CMD_MAPPED; if (cm->cm_flags & AAC_CMD_WAIT) { + aac_fib_header_tole(&fib->Header); aacraid_sync_command(sc, AAC_MONKER_SYNCFIB, cm->cm_fibphys, 0, 0, 0, NULL, NULL); } else if (sc->flags & AAC_FLAGS_SYNC_MODE) { u_int32_t wait = 0; sc->aac_sync_cm = cm; + aac_fib_header_tole(&fib->Header); aacraid_sync_command(sc, AAC_MONKER_SYNCFIB, cm->cm_fibphys, 0, 0, 0, &wait, NULL); } else { @@ -1788,6 +1808,8 @@ aac_init(struct aac_softc *sc) ip->MaxIoSize = sc->aac_max_sectors << 9; ip->MaxFibSize = sc->aac_max_fib_size; + aac_adapter_init_tole(ip); + /* * Do controller-type-specific initialisation */ @@ -1996,18 +2018,24 @@ aac_check_config(struct aac_softc *sc) ccfg->CTCommand.command = CT_GET_CONFIG_STATUS; ccfg->CTCommand.param[CNT_SIZE] = sizeof(struct aac_cf_status_hdr); + aac_cnt_config_tole(ccfg); rval = aac_sync_fib(sc, ContainerCommand, 0, fib, sizeof (struct aac_cnt_config)); + aac_cnt_config_toh(ccfg); + cf_shdr = (struct aac_cf_status_hdr *)ccfg->CTCommand.data; if (rval == 0 && ccfg->Command == ST_OK && ccfg->CTCommand.param[0] == CT_OK) { - if (cf_shdr->action <= CFACT_PAUSE) { + if (le32toh(cf_shdr->action) <= CFACT_PAUSE) { bzero(ccfg, sizeof (*ccfg) - CT_PACKET_SIZE); ccfg->Command = VM_ContainerConfig; ccfg->CTCommand.command = CT_COMMIT_CONFIG; + aac_cnt_config_tole(ccfg); rval = aac_sync_fib(sc, ContainerCommand, 0, fib, sizeof (struct aac_cnt_config)); + aac_cnt_config_toh(ccfg); + if (rval == 0 && ccfg->Command == ST_OK && ccfg->CTCommand.param[0] == CT_OK) { /* successful completion */ @@ -2087,6 +2115,8 @@ static int aac_sync_fib(struct aac_softc *sc, u_int32_t command, u_int32_t xferstate, struct aac_fib *fib, u_int16_t datasize) { + uint32_t ReceiverFibAddress; + fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, ""); mtx_assert(&sc->aac_io_lock, MA_OWNED); @@ -2105,18 +2135,22 @@ aac_sync_fib(struct aac_softc *sc, u_int32_t command, u_int32_t xferstate, fib->Header.Size = sizeof(struct aac_fib_header) + datasize; fib->Header.SenderSize = sizeof(struct aac_fib); fib->Header.SenderFibAddress = 0; /* Not needed */ - fib->Header.u.ReceiverFibAddress = sc->aac_common_busaddr + + ReceiverFibAddress = sc->aac_common_busaddr + offsetof(struct aac_common, ac_sync_fib); + fib->Header.u.ReceiverFibAddress = ReceiverFibAddress; + aac_fib_header_tole(&fib->Header); /* * Give the FIB to the controller, wait for a response. */ if (aacraid_sync_command(sc, AAC_MONKER_SYNCFIB, - fib->Header.u.ReceiverFibAddress, 0, 0, 0, NULL, NULL)) { + ReceiverFibAddress, 0, 0, 0, NULL, NULL)) { fwprintf(sc, HBA_FLAGS_DBG_ERROR_B, "IO error"); + aac_fib_header_toh(&fib->Header); return(EIO); } + aac_fib_header_toh(&fib->Header); return (0); } @@ -2407,10 +2441,13 @@ aac_src_send_command(struct aac_softc *sc, struct aac_command *cm) pFibX->Handle = cm->cm_fib->Header.Handle; pFibX->HostAddress = cm->cm_fibphys; pFibX->Size = cm->cm_fib->Header.Size; + aac_fib_xporthdr_tole(pFibX); address = cm->cm_fibphys - sizeof(struct aac_fib_xporthdr); high_addr = (u_int32_t)(address >> 32); } + aac_fib_header_tole(&cm->cm_fib->Header); + if (fibsize > 31) fibsize = 31; aac_enqueue_busy(cm); @@ -2468,8 +2505,8 @@ aac_describe_controller(struct aac_softc *sc) supp_info = ((struct aac_supplement_adapter_info *)&fib->data[0]); adapter_type = (char *)supp_info->AdapterTypeText; - sc->aac_feature_bits = supp_info->FeatureBits; - sc->aac_support_opt2 = supp_info->SupportedOptions2; + sc->aac_feature_bits = le32toh(supp_info->FeatureBits); + sc->aac_support_opt2 = le32toh(supp_info->SupportedOptions2); } } device_printf(sc->aac_dev, "%s, aacraid driver %d.%d.%d-%d\n", @@ -2487,6 +2524,7 @@ aac_describe_controller(struct aac_softc *sc) /* save the kernel revision structure for later use */ info = (struct aac_adapter_info *)&fib->data[0]; + aac_adapter_info_toh(info); sc->aac_revision = info->KernelRevision; if (bootverbose) { @@ -2720,6 +2758,18 @@ aac_ioctl_event(struct aac_softc *sc, struct aac_event *event, void *arg) /* * Send a FIB supplied from userspace + * + * Currently, sending a FIB from userspace in BE hosts is not supported. + * There are several things that need to be considered in order to + * support this, such as: + * - At least the FIB data part from userspace should already be in LE, + * or else the kernel would need to know all FIB types to be able to + * correctly convert it to BE. + * - SG tables are converted to BE by aacraid_map_command_sg(). This + * conversion should be supressed if the FIB comes from userspace. + * - aacraid_wait_command() calls functions that convert the FIB header + * to LE. But if the header is already in LE, the conversion should not + * be performed. */ static int aac_ioctl_sendfib(struct aac_softc *sc, caddr_t ufib) @@ -2961,6 +3011,8 @@ aac_ioctl_send_raw_srb(struct aac_softc *sc, caddr_t arg) ScsiPortCommandU64 : ScsiPortCommand; cm->cm_sgtable = (struct aac_sg_table *)&srbcmd->sg_map; + aac_srb_tole(srbcmd); + /* send command */ if (transfer_data) { bus_dmamap_load(cm->cm_passthr_dmat, @@ -2978,7 +3030,7 @@ aac_ioctl_send_raw_srb(struct aac_softc *sc, caddr_t arg) mtx_unlock(&sc->aac_io_lock); /* copy data */ - if (transfer_data && (srbcmd->flags & AAC_SRB_FLAGS_DATA_IN)) { + if (transfer_data && (le32toh(srbcmd->flags) & AAC_SRB_FLAGS_DATA_IN)) { if ((error = copyout(cm->cm_data, (void *)(uintptr_t)srb_sg_address, cm->cm_datalen)) != 0) @@ -2989,6 +3041,7 @@ aac_ioctl_send_raw_srb(struct aac_softc *sc, caddr_t arg) } /* status */ + aac_srb_response_toh((struct aac_srb_response *)fib->data); error = copyout(fib->data, user_reply, sizeof(struct aac_srb_response)); out: @@ -3039,7 +3092,7 @@ aac_request_aif(struct aac_softc *sc) /* set AIF marker */ fib->Header.Handle = 0x00800000; fib->Header.Command = AifRequest; - ((struct aac_aif_command *)fib->data)->command = AifReqEvent; + ((struct aac_aif_command *)fib->data)->command = htole32(AifReqEvent); aacraid_map_command_sg(cm, NULL, 0, 0); } @@ -3080,9 +3133,9 @@ aac_handle_aif(struct aac_softc *sc, struct aac_fib *fib) aacraid_print_aif(sc, aif); /* Is it an event that we should care about? */ - switch (aif->command) { + switch (le32toh(aif->command)) { case AifCmdEventNotify: - switch (aif->data.EN.type) { + switch (le32toh(aif->data.EN.type)) { case AifEnAddContainer: case AifEnDeleteContainer: /* @@ -3174,10 +3227,10 @@ aac_handle_aif(struct aac_softc *sc, struct aac_fib *fib) break; case AifEnEnclosureManagement: - switch (aif->data.EN.data.EEE.eventType) { + switch (le32toh(aif->data.EN.data.EEE.eventType)) { case AIF_EM_DRIVE_INSERTION: case AIF_EM_DRIVE_REMOVAL: - channel = aif->data.EN.data.EEE.unitID; + channel = le32toh(aif->data.EN.data.EEE.unitID); if (sc->cam_rescan_cb != NULL) sc->cam_rescan_cb(sc, ((channel>>24) & 0xF) + 1, @@ -3189,7 +3242,7 @@ aac_handle_aif(struct aac_softc *sc, struct aac_fib *fib) case AifEnAddJBOD: case AifEnDeleteJBOD: case AifRawDeviceRemove: - channel = aif->data.EN.data.ECE.container; + channel = le32toh(aif->data.EN.data.ECE.container); if (sc->cam_rescan_cb != NULL) sc->cam_rescan_cb(sc, ((channel>>24) & 0xF) + 1, AAC_CAM_TARGET_WILDCARD); @@ -3209,6 +3262,8 @@ aac_handle_aif(struct aac_softc *sc, struct aac_fib *fib) if (next == 0) sc->aifq_filled = 1; bcopy(fib, &sc->aac_aifq[current], sizeof(struct aac_fib)); + /* Make aifq's FIB header and data LE */ + aac_fib_header_tole(&sc->aac_aifq[current].Header); /* modify AIF contexts */ if (sc->aifq_filled) { for (ctx = sc->fibctx; ctx; ctx = ctx->next) { @@ -3602,6 +3657,7 @@ aac_get_bus_info(struct aac_softc *sc) c_cmd->cmd = CT_GET_SCSI_METHOD; c_cmd->param = 0; + aac_ctcfg_tole(c_cmd); error = aac_sync_fib(sc, ContainerCommand, 0, fib, sizeof(struct aac_ctcfg)); if (error) { @@ -3613,6 +3669,7 @@ aac_get_bus_info(struct aac_softc *sc) } c_resp = (struct aac_ctcfg_resp *)&fib->data[0]; + aac_ctcfg_resp_toh(c_resp); if (c_resp->Status != ST_OK) { device_printf(sc->aac_dev, "VM_ContainerConfig returned 0x%x\n", c_resp->Status); @@ -3632,6 +3689,7 @@ aac_get_bus_info(struct aac_softc *sc) vmi->ObjId = 0; vmi->IoctlCmd = GetBusInfo; + aac_vmioctl_tole(vmi); error = aac_sync_fib(sc, ContainerCommand, 0, fib, sizeof(struct aac_vmi_businf_resp)); if (error) { @@ -3643,6 +3701,7 @@ aac_get_bus_info(struct aac_softc *sc) } vmi_resp = (struct aac_vmi_businf_resp *)&fib->data[0]; + aac_vmi_businf_resp_toh(vmi_resp); if (vmi_resp->Status != ST_OK) { device_printf(sc->aac_dev, "VM_Ioctl returned %d\n", vmi_resp->Status); @@ -3814,6 +3873,7 @@ aac_reset_adapter(struct aac_softc *sc) pc->Min = 1; pc->NoRescan = 1; + aac_pause_command_tole(pc); (void) aac_sync_fib(sc, ContainerCommand, 0, fib, sizeof (struct aac_pause_command)); aac_release_sync_fib(sc); diff --git a/sys/dev/aacraid/aacraid_cam.c b/sys/dev/aacraid/aacraid_cam.c index f35b631daad6..48da7e8d757f 100644 --- a/sys/dev/aacraid/aacraid_cam.c +++ b/sys/dev/aacraid/aacraid_cam.c @@ -69,6 +69,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #ifndef CAM_NEW_TRAN_CODE #define CAM_NEW_TRAN_CODE 1 @@ -417,6 +418,7 @@ aac_container_rw_command(struct cam_sim *sim, union ccb *ccb, u_int8_t *cmdp) if (sc->flags & AAC_FLAGS_NEW_COMM_TYPE2) { struct aac_raw_io2 *raw; + /* NOTE: LE conversion handled at aacraid_map_command_sg() */ raw = (struct aac_raw_io2 *)&fib->data[0]; bzero(raw, sizeof(struct aac_raw_io2)); fib->Header.Command = RawIo2; @@ -432,6 +434,7 @@ aac_container_rw_command(struct cam_sim *sim, union ccb *ccb, u_int8_t *cmdp) raw->flags = RIO2_IO_TYPE_WRITE | RIO2_SG_FORMAT_IEEE1212; } else if (sc->flags & AAC_FLAGS_RAW_IO) { struct aac_raw_io *raw; + /* NOTE: LE conversion handled at aacraid_map_command_sg() */ raw = (struct aac_raw_io *)&fib->data[0]; bzero(raw, sizeof(struct aac_raw_io)); fib->Header.Command = RawIo; @@ -452,6 +455,7 @@ aac_container_rw_command(struct cam_sim *sim, union ccb *ccb, u_int8_t *cmdp) br->ContainerId = ccb->ccb_h.target_id; br->BlockNumber = blockno; br->ByteCount = cm->cm_datalen; + aac_blockread_tole(br); fib->Header.Size += sizeof(struct aac_blockread); cm->cm_sgtable = &br->SgMap; } else { @@ -462,6 +466,7 @@ aac_container_rw_command(struct cam_sim *sim, union ccb *ccb, u_int8_t *cmdp) bw->BlockNumber = blockno; bw->ByteCount = cm->cm_datalen; bw->Stable = CUNSTABLE; + aac_blockwrite_tole(bw); fib->Header.Size += sizeof(struct aac_blockwrite); cm->cm_sgtable = &bw->SgMap; } @@ -476,6 +481,7 @@ aac_container_rw_command(struct cam_sim *sim, union ccb *ccb, u_int8_t *cmdp) br->BlockNumber = blockno; br->Pad = 0; br->Flags = 0; + aac_blockread64_tole(br); fib->Header.Size += sizeof(struct aac_blockread64); cm->cm_sgtable = (struct aac_sg_table *)&br->SgMap64; } else { @@ -487,6 +493,7 @@ aac_container_rw_command(struct cam_sim *sim, union ccb *ccb, u_int8_t *cmdp) bw->BlockNumber = blockno; bw->Pad = 0; bw->Flags = 0; + aac_blockwrite64_tole(bw); fib->Header.Size += sizeof(struct aac_blockwrite64); cm->cm_sgtable = (struct aac_sg_table *)&bw->SgMap64; } @@ -656,9 +663,10 @@ aac_container_special_command(struct cam_sim *sim, union ccb *ccb, AAC_PM_DRIVERSUP_STOP_UNIT); ccfg->CTCommand.param[1] = co->co_mntobj.ObjectId; ccfg->CTCommand.param[2] = 0; /* 1 - immediate */ + aac_cnt_config_tole(ccfg); if (aacraid_wait_command(cm) != 0 || - *(u_int32_t *)&fib->data[0] != 0) { + le32toh(*(u_int32_t *)&fib->data[0]) != 0) { printf("Power Management: Error start/stop container %d\n", co->co_mntobj.ObjectId); } @@ -930,6 +938,7 @@ aac_passthrough_command(struct cam_sim *sim, union ccb *ccb) srb->lun = ccb->ccb_h.target_lun; srb->timeout = ccb->ccb_h.timeout; /* XXX */ srb->retry_limit = 0; + aac_srb_tole(srb); cm->cm_complete = aac_cam_complete; cm->cm_ccb = ccb; @@ -1119,7 +1128,7 @@ aac_container_complete(struct aac_command *cm) fwprintf(cm->cm_sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, ""); ccb = cm->cm_ccb; - status = ((u_int32_t *)cm->cm_fib->data)[0]; + status = le32toh(((u_int32_t *)cm->cm_fib->data)[0]); if (cm->cm_flags & AAC_CMD_RESET) { ccb->ccb_h.status = CAM_SCSI_BUS_RESET; @@ -1146,6 +1155,7 @@ aac_cam_complete(struct aac_command *cm) fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, ""); ccb = cm->cm_ccb; srbr = (struct aac_srb_response *)&cm->cm_fib->data[0]; + aac_srb_response_toh(srbr); if (cm->cm_flags & AAC_CMD_FASTRESP) { /* fast response */ @@ -1297,6 +1307,7 @@ aac_cam_reset_bus(struct cam_sim *sim, union ccb *ccb) rbc = (struct aac_resetbus *)&vmi->IoctlBuf[0]; rbc->BusNumber = camsc->inf->BusNumber - 1; + aac_vmioctl_tole(vmi); if (aacraid_wait_command(cm) != 0) { device_printf(sc->aac_dev,"Error sending ResetBus command\n"); diff --git a/sys/dev/aacraid/aacraid_endian.c b/sys/dev/aacraid/aacraid_endian.c new file mode 100644 index 000000000000..29da6c4d4d4f --- /dev/null +++ b/sys/dev/aacraid/aacraid_endian.c @@ -0,0 +1,389 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2019 Leandro Lupori + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include + +#include +#include + +#if _BYTE_ORDER != _LITTLE_ENDIAN + +#define TOH2(field, bits) field = le##bits##toh(field) +#define TOH(field, bits) TOH2(field, bits) + +#define TOLE2(field, bits) field = htole##bits(field) +#define TOLE(field, bits) TOLE2(field, bits) + +/* Convert from Little-Endian to host order (TOH) */ + +void +aac_fib_header_toh(struct aac_fib_header *ptr) +{ + TOH(ptr->XferState, 32); + TOH(ptr->Command, 16); + TOH(ptr->Size, 16); + TOH(ptr->SenderSize, 16); + TOH(ptr->SenderFibAddress, 32); + TOH(ptr->u.ReceiverFibAddress, 32); + TOH(ptr->Handle, 32); + TOH(ptr->Previous, 32); + TOH(ptr->Next, 32); +} + +void +aac_adapter_info_toh(struct aac_adapter_info *ptr) +{ + TOH(ptr->PlatformBase, 32); + TOH(ptr->CpuArchitecture, 32); + TOH(ptr->CpuVariant, 32); + TOH(ptr->ClockSpeed, 32); + TOH(ptr->ExecutionMem, 32); + TOH(ptr->BufferMem, 32); + TOH(ptr->TotalMem, 32); + + TOH(ptr->KernelRevision.buildNumber, 32); + TOH(ptr->MonitorRevision.buildNumber, 32); + TOH(ptr->HardwareRevision.buildNumber, 32); + TOH(ptr->BIOSRevision.buildNumber, 32); + + TOH(ptr->ClusteringEnabled, 32); + TOH(ptr->ClusterChannelMask, 32); + TOH(ptr->SerialNumber, 64); + TOH(ptr->batteryPlatform, 32); + TOH(ptr->SupportedOptions, 32); + TOH(ptr->OemVariant, 32); +} + +void +aac_container_creation_toh(struct aac_container_creation *ptr) +{ + u_int32_t *date = (u_int32_t *)ptr + 1; + + *date = le32toh(*date); + TOH(ptr->ViaAdapterSerialNumber, 64); +} + +void +aac_mntobj_toh(struct aac_mntobj *ptr) +{ + TOH(ptr->ObjectId, 32); + aac_container_creation_toh(&ptr->CreateInfo); + TOH(ptr->Capacity, 32); + TOH(ptr->VolType, 32); + TOH(ptr->ObjType, 32); + TOH(ptr->ContentState, 32); + TOH(ptr->ObjExtension.BlockDevice.BlockSize, 32); + TOH(ptr->ObjExtension.BlockDevice.bdLgclPhysMap, 32); + TOH(ptr->AlterEgoId, 32); + TOH(ptr->CapacityHigh, 32); +} + +void +aac_mntinforesp_toh(struct aac_mntinforesp *ptr) +{ + TOH(ptr->Status, 32); + TOH(ptr->MntType, 32); + TOH(ptr->MntRespCount, 32); + aac_mntobj_toh(&ptr->MntTable[0]); +} + +void +aac_fsa_ctm_toh(struct aac_fsa_ctm *ptr) +{ + int i; + + TOH(ptr->command, 32); + for (i = 0; i < CT_FIB_PARAMS; i++) + TOH(ptr->param[i], 32); +} + +void +aac_cnt_config_toh(struct aac_cnt_config *ptr) +{ + TOH(ptr->Command, 32); + aac_fsa_ctm_toh(&ptr->CTCommand); +} + +void +aac_ctcfg_resp_toh(struct aac_ctcfg_resp *ptr) +{ + TOH(ptr->Status, 32); + TOH(ptr->resp, 32); + TOH(ptr->param, 32); +} + +void +aac_getbusinf_toh(struct aac_getbusinf *ptr) +{ + TOH(ptr->ProbeComplete, 32); + TOH(ptr->BusCount, 32); + TOH(ptr->TargetsPerBus, 32); +} + +void +aac_vmi_businf_resp_toh(struct aac_vmi_businf_resp *ptr) +{ + TOH(ptr->Status, 32); + TOH(ptr->ObjType, 32); + TOH(ptr->MethId, 32); + TOH(ptr->ObjId, 32); + TOH(ptr->IoctlCmd, 32); + aac_getbusinf_toh(&ptr->BusInf); +} + +void +aac_srb_response_toh(struct aac_srb_response *ptr) +{ + TOH(ptr->fib_status, 32); + TOH(ptr->srb_status, 32); + TOH(ptr->scsi_status, 32); + TOH(ptr->data_len, 32); + TOH(ptr->sense_len, 32); +} + +/* Convert from host order to Little-Endian (TOLE) */ + +void +aac_adapter_init_tole(struct aac_adapter_init *ptr) +{ + TOLE(ptr->InitStructRevision, 32); + TOLE(ptr->NoOfMSIXVectors, 32); + TOLE(ptr->FilesystemRevision, 32); + TOLE(ptr->CommHeaderAddress, 32); + TOLE(ptr->FastIoCommAreaAddress, 32); + TOLE(ptr->AdapterFibsPhysicalAddress, 32); + TOLE(ptr->AdapterFibsVirtualAddress, 32); + TOLE(ptr->AdapterFibsSize, 32); + TOLE(ptr->AdapterFibAlign, 32); + TOLE(ptr->PrintfBufferAddress, 32); + TOLE(ptr->PrintfBufferSize, 32); + TOLE(ptr->HostPhysMemPages, 32); + TOLE(ptr->HostElapsedSeconds, 32); + TOLE(ptr->InitFlags, 32); + TOLE(ptr->MaxIoCommands, 32); + TOLE(ptr->MaxIoSize, 32); + TOLE(ptr->MaxFibSize, 32); + TOLE(ptr->MaxNumAif, 32); + TOLE(ptr->HostRRQ_AddrLow, 32); + TOLE(ptr->HostRRQ_AddrHigh, 32); +} + +void +aac_fib_header_tole(struct aac_fib_header *ptr) +{ + TOLE(ptr->XferState, 32); + TOLE(ptr->Command, 16); + TOLE(ptr->Size, 16); + TOLE(ptr->SenderSize, 16); + TOLE(ptr->SenderFibAddress, 32); + TOLE(ptr->u.ReceiverFibAddress, 32); + TOLE(ptr->Handle, 32); + TOLE(ptr->Previous, 32); + TOLE(ptr->Next, 32); +} + +void +aac_mntinfo_tole(struct aac_mntinfo *ptr) +{ + TOLE(ptr->Command, 32); + TOLE(ptr->MntType, 32); + TOLE(ptr->MntCount, 32); +} + +void +aac_fsa_ctm_tole(struct aac_fsa_ctm *ptr) +{ + int i; + + TOLE(ptr->command, 32); + for (i = 0; i < CT_FIB_PARAMS; i++) + TOLE(ptr->param[i], 32); +} + +void +aac_cnt_config_tole(struct aac_cnt_config *ptr) +{ + TOLE(ptr->Command, 32); + aac_fsa_ctm_tole(&ptr->CTCommand); +} + +void +aac_raw_io_tole(struct aac_raw_io *ptr) +{ + TOLE(ptr->BlockNumber, 64); + TOLE(ptr->ByteCount, 32); + TOLE(ptr->ContainerId, 16); + TOLE(ptr->Flags, 16); + TOLE(ptr->BpTotal, 16); + TOLE(ptr->BpComplete, 16); +} + +void +aac_raw_io2_tole(struct aac_raw_io2 *ptr) +{ + TOLE(ptr->strtBlkLow, 32); + TOLE(ptr->strtBlkHigh, 32); + TOLE(ptr->byteCnt, 32); + TOLE(ptr->ldNum, 16); + TOLE(ptr->flags, 16); + TOLE(ptr->sgeFirstSize, 32); + TOLE(ptr->sgeNominalSize, 32); +} + +void +aac_fib_xporthdr_tole(struct aac_fib_xporthdr *ptr) +{ + TOLE(ptr->HostAddress, 64); + TOLE(ptr->Size, 32); + TOLE(ptr->Handle, 32); +} + +void +aac_ctcfg_tole(struct aac_ctcfg *ptr) +{ + TOLE(ptr->Command, 32); + TOLE(ptr->cmd, 32); + TOLE(ptr->param, 32); +} + +void +aac_vmioctl_tole(struct aac_vmioctl *ptr) +{ + TOLE(ptr->Command, 32); + TOLE(ptr->ObjType, 32); + TOLE(ptr->MethId, 32); + TOLE(ptr->ObjId, 32); + TOLE(ptr->IoctlCmd, 32); + TOLE(ptr->IoctlBuf[0], 32); +} + +void +aac_pause_command_tole(struct aac_pause_command *ptr) +{ + TOLE(ptr->Command, 32); + TOLE(ptr->Type, 32); + TOLE(ptr->Timeout, 32); + TOLE(ptr->Min, 32); + TOLE(ptr->NoRescan, 32); + TOLE(ptr->Parm3, 32); + TOLE(ptr->Parm4, 32); + TOLE(ptr->Count, 32); +} + +void +aac_srb_tole(struct aac_srb *ptr) +{ + TOLE(ptr->function, 32); + TOLE(ptr->bus, 32); + TOLE(ptr->target, 32); + TOLE(ptr->lun, 32); + TOLE(ptr->timeout, 32); + TOLE(ptr->flags, 32); + TOLE(ptr->data_len, 32); + TOLE(ptr->retry_limit, 32); + TOLE(ptr->cdb_len, 32); +} + +void +aac_sge_ieee1212_tole(struct aac_sge_ieee1212 *ptr) +{ + TOLE(ptr->addrLow, 32); + TOLE(ptr->addrHigh, 32); + TOLE(ptr->length, 32); + TOLE(ptr->flags, 32); +} + +void +aac_sg_entryraw_tole(struct aac_sg_entryraw *ptr) +{ + TOLE(ptr->Next, 32); + TOLE(ptr->Prev, 32); + TOLE(ptr->SgAddress, 64); + TOLE(ptr->SgByteCount, 32); + TOLE(ptr->Flags, 32); +} + +void +aac_sg_entry_tole(struct aac_sg_entry *ptr) +{ + TOLE(ptr->SgAddress, 32); + TOLE(ptr->SgByteCount, 32); +} + +void +aac_sg_entry64_tole(struct aac_sg_entry64 *ptr) +{ + TOLE(ptr->SgAddress, 64); + TOLE(ptr->SgByteCount, 32); +} + +void +aac_blockread_tole(struct aac_blockread *ptr) +{ + TOLE(ptr->Command, 32); + TOLE(ptr->ContainerId, 32); + TOLE(ptr->BlockNumber, 32); + TOLE(ptr->ByteCount, 32); +} + +void +aac_blockwrite_tole(struct aac_blockwrite *ptr) +{ + TOLE(ptr->Command, 32); + TOLE(ptr->ContainerId, 32); + TOLE(ptr->BlockNumber, 32); + TOLE(ptr->ByteCount, 32); + TOLE(ptr->Stable, 32); +} + +void +aac_blockread64_tole(struct aac_blockread64 *ptr) +{ + TOLE(ptr->Command, 32); + TOLE(ptr->ContainerId, 16); + TOLE(ptr->SectorCount, 16); + TOLE(ptr->BlockNumber, 32); + TOLE(ptr->Pad, 16); + TOLE(ptr->Flags, 16); +} + +void +aac_blockwrite64_tole(struct aac_blockwrite64 *ptr) +{ + TOLE(ptr->Command, 32); + TOLE(ptr->ContainerId, 16); + TOLE(ptr->SectorCount, 16); + TOLE(ptr->BlockNumber, 32); + TOLE(ptr->Pad, 16); + TOLE(ptr->Flags, 16); +} + +#endif diff --git a/sys/dev/aacraid/aacraid_endian.h b/sys/dev/aacraid/aacraid_endian.h new file mode 100644 index 000000000000..c57585db8310 --- /dev/null +++ b/sys/dev/aacraid/aacraid_endian.h @@ -0,0 +1,114 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2019 Leandro Lupori + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef AACRAID_ENDIAN_H +#define AACRAID_ENDIAN_H + +#include + +#if _BYTE_ORDER == _LITTLE_ENDIAN + +/* On Little-Endian (LE) hosts, make all FIB data conversion functions empty. */ + +/* Convert from Little-Endian to host order (TOH) */ +#define aac_fib_header_toh(ptr) +#define aac_adapter_info_toh(ptr) +#define aac_container_creation_toh(ptr) +#define aac_mntobj_toh(ptr) +#define aac_mntinforesp_toh(ptr) +#define aac_fsa_ctm_toh(ptr) +#define aac_cnt_config_toh(ptr) +#define aac_ctcfg_resp_toh(ptr) +#define aac_getbusinf_toh(ptr) +#define aac_vmi_businf_resp_toh(ptr) +#define aac_srb_response_toh(ptr) + +/* Convert from host order to Little-Endian (TOLE) */ +#define aac_adapter_init_tole(ptr) +#define aac_fib_header_tole(ptr) +#define aac_mntinfo_tole(ptr) +#define aac_fsa_ctm_tole(ptr) +#define aac_cnt_config_tole(ptr) +#define aac_raw_io_tole(ptr) +#define aac_raw_io2_tole(ptr) +#define aac_fib_xporthdr_tole(ptr) +#define aac_ctcfg_tole(ptr) +#define aac_vmioctl_tole(ptr) +#define aac_pause_command_tole(ptr) +#define aac_srb_tole(ptr) +#define aac_sge_ieee1212_tole(ptr) +#define aac_sg_entryraw_tole(ptr) +#define aac_sg_entry_tole(ptr) +#define aac_sg_entry64_tole(ptr) +#define aac_blockread_tole(ptr) +#define aac_blockwrite_tole(ptr) +#define aac_blockread64_tole(ptr) +#define aac_blockwrite64_tole(ptr) + + +#else /* _BYTE_ORDER != _LITTLE_ENDIAN */ + +/* Convert from Little-Endian to host order (TOH) */ +void aac_fib_header_toh(struct aac_fib_header *ptr); +void aac_adapter_info_toh(struct aac_adapter_info *ptr); +void aac_container_creation_toh(struct aac_container_creation *ptr); +void aac_mntobj_toh(struct aac_mntobj *ptr); +void aac_mntinforesp_toh(struct aac_mntinforesp *ptr); +void aac_fsa_ctm_toh(struct aac_fsa_ctm *ptr); +void aac_cnt_config_toh(struct aac_cnt_config *ptr); +void aac_ctcfg_resp_toh(struct aac_ctcfg_resp *ptr); +void aac_getbusinf_toh(struct aac_getbusinf *ptr); +void aac_vmi_businf_resp_toh(struct aac_vmi_businf_resp *ptr); +void aac_srb_response_toh(struct aac_srb_response *ptr); + +/* Convert from host order to Little-Endian (TOLE) */ +void aac_adapter_init_tole(struct aac_adapter_init *ptr); +void aac_fib_header_tole(struct aac_fib_header *ptr); +void aac_mntinfo_tole(struct aac_mntinfo *ptr); +void aac_fsa_ctm_tole(struct aac_fsa_ctm *ptr); +void aac_cnt_config_tole(struct aac_cnt_config *ptr); +void aac_raw_io_tole(struct aac_raw_io *ptr); +void aac_raw_io2_tole(struct aac_raw_io2 *ptr); +void aac_fib_xporthdr_tole(struct aac_fib_xporthdr *ptr); +void aac_ctcfg_tole(struct aac_ctcfg *ptr); +void aac_vmioctl_tole(struct aac_vmioctl *ptr); +void aac_pause_command_tole(struct aac_pause_command *ptr); +void aac_srb_tole(struct aac_srb *ptr); +void aac_sge_ieee1212_tole(struct aac_sge_ieee1212 *ptr); +void aac_sg_entryraw_tole(struct aac_sg_entryraw *ptr); +void aac_sg_entry_tole(struct aac_sg_entry *ptr); +void aac_sg_entry64_tole(struct aac_sg_entry64 *ptr); +void aac_blockread_tole(struct aac_blockread *ptr); +void aac_blockwrite_tole(struct aac_blockwrite *ptr); +void aac_blockread64_tole(struct aac_blockread64 *ptr); +void aac_blockwrite64_tole(struct aac_blockwrite64 *ptr); + +#endif + +#endif diff --git a/sys/modules/Makefile b/sys/modules/Makefile index 461998568040..af8b0d2b471e 100644 --- a/sys/modules/Makefile +++ b/sys/modules/Makefile @@ -748,6 +748,7 @@ _cpsw= cpsw .endif .if ${MACHINE_CPUARCH} == "powerpc" +_aacraid= aacraid _agp= agp _an= an _cardbus= cardbus diff --git a/sys/modules/aacraid/Makefile b/sys/modules/aacraid/Makefile index 8852d477b739..8bbe1d7db708 100644 --- a/sys/modules/aacraid/Makefile +++ b/sys/modules/aacraid/Makefile @@ -8,6 +8,9 @@ SUBDIR= aacraid_linux KMOD= aacraid SRCS= aacraid.c aacraid_pci.c aacraid_cam.c +.if ${MACHINE_CPUARCH} == "powerpc" +SRCS+= aacraid_endian.c +.endif SRCS+= opt_scsi.h opt_cam.h opt_aacraid.h SRCS+= device_if.h bus_if.h pci_if.h diff --git a/sys/powerpc/conf/GENERIC64 b/sys/powerpc/conf/GENERIC64 index 012731854520..0c2d96afe88a 100644 --- a/sys/powerpc/conf/GENERIC64 +++ b/sys/powerpc/conf/GENERIC64 @@ -136,6 +136,7 @@ options NVME_USE_NVD=0 # prefer the cam(4) based nda(4) driver device nvd # expose NVMe namespaces as disks, depends on nvme # SCSI Controllers +device aacraid # Adaptec by PMC RAID device ahc # AHA2940 and onboard AIC7xxx devices options AHC_ALLOW_MEMIO # Attempt to use memory mapped I/O device isp # Qlogic family From 2f7242ed33fe33da4f407da2b7c9ea09a308a9f4 Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Thu, 5 Mar 2020 20:53:43 +0000 Subject: [PATCH 04/19] libelf: rationalize error handling in ELF note conversion Previously _libelf_cvt_NOTE_tom (to host) returned false if a note's namesz + descsz exceeded the buffer size, while _libelf_cvt_NOTE_tof (to file) silently truncated. Return false in the latter case too. Sponsored by: The FreeBSD Foundation --- contrib/elftoolchain/libelf/libelf_convert.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/elftoolchain/libelf/libelf_convert.m4 b/contrib/elftoolchain/libelf/libelf_convert.m4 index bb601ad92841..71c730426b87 100644 --- a/contrib/elftoolchain/libelf/libelf_convert.m4 +++ b/contrib/elftoolchain/libelf/libelf_convert.m4 @@ -1022,7 +1022,7 @@ _libelf_cvt_NOTE_tof(unsigned char *dst, size_t dsz, unsigned char *src, count -= sizeof(Elf_Note); if (count < sz) - sz = count; + return (0); (void) memcpy(dst, src, sz); From 3f16af55b26d45dd8ab921f518fe207f27a9b4c0 Mon Sep 17 00:00:00 2001 From: Gleb Smirnoff Date: Thu, 5 Mar 2020 21:01:47 +0000 Subject: [PATCH 05/19] Align the buffer to the alignment of the structure we expect. Submitted by: Slawa Olhovchenkov --- sbin/mount_nfs/mount_nfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbin/mount_nfs/mount_nfs.c b/sbin/mount_nfs/mount_nfs.c index 8d8ddac62224..e1eaf206e982 100644 --- a/sbin/mount_nfs/mount_nfs.c +++ b/sbin/mount_nfs/mount_nfs.c @@ -514,7 +514,7 @@ sec_num_to_name(int flavor) static time_t rtm_ifinfo_sleep(time_t sec) { - char buf[2048]; + char buf[2048] __aligned(__alignof(struct if_msghdr)); fd_set rfds; struct timeval tv, start; ssize_t nread; From 924e10b809a9fcbc8688c1b5848f60b48e6103fe Mon Sep 17 00:00:00 2001 From: Kyle Evans Date: Thu, 5 Mar 2020 22:45:16 +0000 Subject: [PATCH 06/19] tftpd: tests: raise targeted cstd to c11 r358556 added alignas() use to the functional tests, which isn't defined until C11. Raise the -std to C11 to fix the build under freebsd-gcc{6,9}. Reported by: mhorne, Jenkins/CI --- libexec/tftpd/tests/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/libexec/tftpd/tests/Makefile b/libexec/tftpd/tests/Makefile index 06c5537372a7..9aa420cec1a5 100644 --- a/libexec/tftpd/tests/Makefile +++ b/libexec/tftpd/tests/Makefile @@ -10,5 +10,6 @@ TEST_METADATA.functional+= timeout=15 LIBADD= util WARNS?= 6 +CSTD= c11 .include From 00797360b52bd2c0adbad4575054e3d9e2b4529f Mon Sep 17 00:00:00 2001 From: Justin Hibbits Date: Fri, 6 Mar 2020 01:45:03 +0000 Subject: [PATCH 07/19] powerpc/powerpc64: Enforce natural alignment in memcpy Summary: POWER architecture CPUs (Book-S) require natural alignment for cache-inhibited storage accesses. Since we can't know the caching model for a page ahead of time, always enforce natural alignment in memcpy. This fixes a SIGBUS in X with acceleration enabled on POWER9. As part of this, revert r358672, it's no longer necessary with this fix. Regression tested by alfredo. Reviewed by: alfredo Differential Revision: https://reviews.freebsd.org/D23969 --- lib/libc/powerpc64/string/bcopy_resolver.c | 2 +- lib/libc/powerpc64/string/memcpy.S | 11 +++++++++++ lib/libc/powerpc64/string/memcpy_vsx.S | 1 + 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/libc/powerpc64/string/bcopy_resolver.c b/lib/libc/powerpc64/string/bcopy_resolver.c index 34b88d6ccbe4..54664f58cabe 100644 --- a/lib/libc/powerpc64/string/bcopy_resolver.c +++ b/lib/libc/powerpc64/string/bcopy_resolver.c @@ -66,7 +66,7 @@ DEFINE_UIFUNC(, FN_RET, FN_NAME, FN_PARAMS) * Since POWER ISA 2.07B this is solved transparently * by the hardware */ - if (cpu_features2 & PPC_FEATURE2_ARCH_2_07) + if (cpu_features2 & PPC_FEATURE_HAS_VSX) return (FN_NAME_VSX); else return (FN_NAME_NOVSX); diff --git a/lib/libc/powerpc64/string/memcpy.S b/lib/libc/powerpc64/string/memcpy.S index 2ea676bf67a9..f88708239f4f 100644 --- a/lib/libc/powerpc64/string/memcpy.S +++ b/lib/libc/powerpc64/string/memcpy.S @@ -39,6 +39,11 @@ WEAK_REFERENCE(__memcpy, memcpy); #define BLOCK_BYTES (1 << BLOCK_BITS) #define BLOCK_MASK (BLOCK_BYTES - 1) +/* Minimum 8 byte alignment, to avoid cache-inhibited alignment faults. */ +#ifndef ALIGN_MASK +#define ALIGN_MASK 0x7 +#endif + /* * r3: dst * r4: src @@ -48,6 +53,12 @@ ENTRY(FN_NAME) cmpdi %r5, 0 /* len == 0? nothing to do */ beqlr- + /* If src and dst are relatively misaligned, do byte copies. */ + andi. %r8, %r3, ALIGN_MASK + andi. %r7, %r4, ALIGN_MASK + cmpd %r8, %r7 + mr %r7, %r5 + bne+ .Lcopy_remaining_fix_index_byte mr %r8, %r3 /* save dst */ /* align src */ diff --git a/lib/libc/powerpc64/string/memcpy_vsx.S b/lib/libc/powerpc64/string/memcpy_vsx.S index 708eb7d9f45d..83dd84ef7ee0 100644 --- a/lib/libc/powerpc64/string/memcpy_vsx.S +++ b/lib/libc/powerpc64/string/memcpy_vsx.S @@ -30,6 +30,7 @@ #define FN_NAME __memcpy_vsx #define BLOCK_BITS 6 +#define ALIGN_MASK 0xf /* * r5: bytes to copy (multiple of BLOCK_BYTES) From b21fe1ab67f0453418ddfd251b41d9eade10af10 Mon Sep 17 00:00:00 2001 From: Justin Hibbits Date: Fri, 6 Mar 2020 01:50:15 +0000 Subject: [PATCH 08/19] Fix a mistaken conditional in mfi_tbolt_send_frame() As written, the condition of (cdb[0] != 0x28 || cdb[0] != 0x2A) will always be true, since if it's one, it's obviously not the other. Reading the code, the intent appears to be that it should only perform the operation if it's neither, otherwise the conditional can be elided. Found by clang 10. --- sys/dev/mfi/mfi_tbolt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/mfi/mfi_tbolt.c b/sys/dev/mfi/mfi_tbolt.c index d7397d2a2ccc..40ba160205ac 100644 --- a/sys/dev/mfi/mfi_tbolt.c +++ b/sys/dev/mfi/mfi_tbolt.c @@ -1109,7 +1109,7 @@ mfi_tbolt_send_frame(struct mfi_softc *sc, struct mfi_command *cm) if (hdr->cmd == MFI_CMD_PD_SCSI_IO) { /* check for inquiry commands coming from CLI */ - if (cdb[0] != 0x28 || cdb[0] != 0x2A) { + if (cdb[0] != 0x28 && cdb[0] != 0x2A) { if ((req_desc = mfi_tbolt_build_mpt_cmd(sc, cm)) == NULL) { device_printf(sc->mfi_dev, "Mapping from MFI " From 021abafa5c0ae1197bac26283ac367e065dcebfd Mon Sep 17 00:00:00 2001 From: Justin Hibbits Date: Fri, 6 Mar 2020 02:30:04 +0000 Subject: [PATCH 09/19] Finish revert of r358672, missed in r358688. Manual reverts never succeed correctly. Reported by: luporl --- lib/libc/powerpc64/string/bcopy_resolver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/libc/powerpc64/string/bcopy_resolver.c b/lib/libc/powerpc64/string/bcopy_resolver.c index 54664f58cabe..1991a2998a4d 100644 --- a/lib/libc/powerpc64/string/bcopy_resolver.c +++ b/lib/libc/powerpc64/string/bcopy_resolver.c @@ -66,7 +66,7 @@ DEFINE_UIFUNC(, FN_RET, FN_NAME, FN_PARAMS) * Since POWER ISA 2.07B this is solved transparently * by the hardware */ - if (cpu_features2 & PPC_FEATURE_HAS_VSX) + if (cpu_features & PPC_FEATURE_HAS_VSX) return (FN_NAME_VSX); else return (FN_NAME_NOVSX); From dcfc676147a0d9c516b6891c874d0809165c1fcc Mon Sep 17 00:00:00 2001 From: Justin Hibbits Date: Fri, 6 Mar 2020 03:46:48 +0000 Subject: [PATCH 10/19] powerpc/memcpy: Don't predict the src and dst will be misaligned Predicting misalignment will pessimize the expected common case. Don't predict true or false in thise case. --- lib/libc/powerpc64/string/memcpy.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/libc/powerpc64/string/memcpy.S b/lib/libc/powerpc64/string/memcpy.S index f88708239f4f..3e6649711382 100644 --- a/lib/libc/powerpc64/string/memcpy.S +++ b/lib/libc/powerpc64/string/memcpy.S @@ -58,7 +58,7 @@ ENTRY(FN_NAME) andi. %r7, %r4, ALIGN_MASK cmpd %r8, %r7 mr %r7, %r5 - bne+ .Lcopy_remaining_fix_index_byte + bne .Lcopy_remaining_fix_index_byte mr %r8, %r3 /* save dst */ /* align src */ From 46abd6a27e7333b45dd5735ac23b64361634a138 Mon Sep 17 00:00:00 2001 From: Stanislav Galabov Date: Fri, 6 Mar 2020 08:50:18 +0000 Subject: [PATCH 11/19] Add Gigabit Ethernet support for RT3883 and RT2880 Ralink/Mediatek SoCs Submitted by: yamori813@yahoo.co.jp Reported by: yamori813@yahoo.co.jp Reviewed by: sgalabov, ray Obtained from: yamori813@yahoo.co.jp Differential Revision: https://reviews.freebsd.org/D22618 --- sys/dev/rt/if_rt.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/sys/dev/rt/if_rt.c b/sys/dev/rt/if_rt.c index 2bb81fe98c79..2c9c503ccf91 100644 --- a/sys/dev/rt/if_rt.c +++ b/sys/dev/rt/if_rt.c @@ -101,6 +101,7 @@ __FBSDID("$FreeBSD$"); #define RT_CHIPID_RT2880 0x2880 #define RT_CHIPID_RT3050 0x3050 +#define RT_CHIPID_RT3883 0x3883 #define RT_CHIPID_RT5350 0x5350 #define RT_CHIPID_MT7620 0x7620 #define RT_CHIPID_MT7621 0x7621 @@ -111,7 +112,7 @@ static const struct ofw_compat_data rt_compat_data[] = { { "ralink,rt2880-eth", RT_CHIPID_RT2880 }, { "ralink,rt3050-eth", RT_CHIPID_RT3050 }, { "ralink,rt3352-eth", RT_CHIPID_RT3050 }, - { "ralink,rt3883-eth", RT_CHIPID_RT3050 }, + { "ralink,rt3883-eth", RT_CHIPID_RT3883 }, { "ralink,rt5350-eth", RT_CHIPID_RT5350 }, { "ralink,mt7620a-eth", RT_CHIPID_MT7620 }, { "mediatek,mt7620-eth", RT_CHIPID_MT7620 }, @@ -355,10 +356,18 @@ rt_attach(device_t dev) struct rt_softc *sc; struct ifnet *ifp; int error, i; +#ifdef FDT + phandle_t node; + char fdtval[32]; +#endif sc = device_get_softc(dev); sc->dev = dev; +#ifdef FDT + node = ofw_bus_get_node(sc->dev); +#endif + mtx_init(&sc->lock, device_get_nameunit(dev), MTX_NETWORK_LOCK, MTX_DEF | MTX_RECURSE); @@ -480,8 +489,16 @@ rt_attach(device_t dev) GDM_DST_PORT_CPU << GDM_OFRC_P_SHIFT /* fwd Other to CPU */ )); - if (sc->rt_chipid == RT_CHIPID_RT2880) - RT_WRITE(sc, MDIO_CFG, MDIO_2880_100T_INIT); +#ifdef FDT + if (sc->rt_chipid == RT_CHIPID_RT2880 || + sc->rt_chipid == RT_CHIPID_RT3883) { + if (OF_getprop(node, "port-mode", fdtval, sizeof(fdtval)) > 0 && + strcmp(fdtval, "gigasw") == 0) + RT_WRITE(sc, MDIO_CFG, MDIO_2880_GIGA_INIT); + else + RT_WRITE(sc, MDIO_CFG, MDIO_2880_100T_INIT); + } +#endif /* allocate Tx and Rx rings */ for (i = 0; i < RT_SOFTC_TX_RING_COUNT; i++) { @@ -2912,7 +2929,7 @@ rtmdio_probe(device_t dev) if (!ofw_bus_is_compatible(dev, "ralink,rt2880-mdio")) return (ENXIO); - device_set_desc(dev, "FV built-in ethernet interface, MDIO controller"); + device_set_desc(dev, "RT built-in ethernet interface, MDIO controller"); return(0); } From 5d4562cb32a3aa6ea55a561f7543b0cd05a9172e Mon Sep 17 00:00:00 2001 From: Hans Petter Selasky Date: Fri, 6 Mar 2020 09:59:07 +0000 Subject: [PATCH 12/19] Fix some whitespace issues in ipoib. MFC after: 1 week Sponsored by: Mellanox Technologies --- sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c b/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c index ed5ad1f5fad2..5bdeb4cb11ff 100644 --- a/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c @@ -1760,12 +1760,12 @@ module_exit(ipoib_cleanup_module); static int ipoib_evhand(module_t mod, int event, void *arg) { - return (0); + return (0); } static moduledata_t ipoib_mod = { - .name = "ipoib", - .evhand = ipoib_evhand, + .name = "ipoib", + .evhand = ipoib_evhand, }; DECLARE_MODULE(ipoib, ipoib_mod, SI_SUB_LAST, SI_ORDER_ANY); From 4d4fcf9cd2a01c614ef115c9911a53325a0bbd5b Mon Sep 17 00:00:00 2001 From: Hans Petter Selasky Date: Fri, 6 Mar 2020 11:26:16 +0000 Subject: [PATCH 13/19] Define more subsystem orders. Intended for use with module_init_order() in the LinuxKPI. MFC after: 1 week Sponsored by: Mellanox Technologies --- sys/sys/kernel.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sys/sys/kernel.h b/sys/sys/kernel.h index fa6accf6156b..839f26706f47 100644 --- a/sys/sys/kernel.h +++ b/sys/sys/kernel.h @@ -183,6 +183,10 @@ enum sysinit_elem_order { SI_ORDER_SECOND = 0x0000001, /* second*/ SI_ORDER_THIRD = 0x0000002, /* third*/ SI_ORDER_FOURTH = 0x0000003, /* fourth*/ + SI_ORDER_FIFTH = 0x0000004, /* fifth*/ + SI_ORDER_SIXTH = 0x0000005, /* sixth*/ + SI_ORDER_SEVENTH = 0x0000006, /* seventh*/ + SI_ORDER_EIGHTH = 0x0000007, /* eighth*/ SI_ORDER_MIDDLE = 0x1000000, /* somewhere in the middle */ SI_ORDER_ANY = 0xfffffff /* last*/ }; From c65f571c898b67f8c455bcf5447f8c1397880c69 Mon Sep 17 00:00:00 2001 From: Leandro Lupori Date: Fri, 6 Mar 2020 12:37:04 +0000 Subject: [PATCH 14/19] ixl: Add missing conversions from/to LE16 This fixes some errors on PPC64, during attach and when trying to assign an IP to an interface. With this change, basic operation of X710 NICs is now possible. This also fixes builds with IXL_DEBUG enabled Reviewed by: erj Sponsored by: Eldorado Research Institute (eldorado.org.br) Differential Revision: https://reviews.freebsd.org/D23975 --- sys/dev/ixl/if_ixl.c | 9 +++++---- sys/dev/ixl/ixl_pf_main.c | 26 +++++++++++++++----------- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/sys/dev/ixl/if_ixl.c b/sys/dev/ixl/if_ixl.c index d84a55d6d99e..e6adade93498 100644 --- a/sys/dev/ixl/if_ixl.c +++ b/sys/dev/ixl/if_ixl.c @@ -398,11 +398,11 @@ ixl_if_attach_pre(if_ctx_t ctx) enum i40e_status_code status; int error = 0; - INIT_DBG_DEV(dev, "begin"); - dev = iflib_get_dev(ctx); pf = iflib_get_softc(ctx); + INIT_DBG_DEV(dev, "begin"); + vsi = &pf->vsi; vsi->back = pf; pf->dev = dev; @@ -588,10 +588,11 @@ ixl_if_attach_post(if_ctx_t ctx) int error = 0; enum i40e_status_code status; - INIT_DBG_DEV(dev, "begin"); - dev = iflib_get_dev(ctx); pf = iflib_get_softc(ctx); + + INIT_DBG_DEV(dev, "begin"); + vsi = &pf->vsi; vsi->ifp = iflib_get_ifp(ctx); hw = &pf->hw; diff --git a/sys/dev/ixl/ixl_pf_main.c b/sys/dev/ixl/ixl_pf_main.c index eefdd22ec828..7979aa0a69d9 100644 --- a/sys/dev/ixl/ixl_pf_main.c +++ b/sys/dev/ixl/ixl_pf_main.c @@ -1123,20 +1123,22 @@ ixl_switch_config(struct ixl_pf *pf) if (pf->dbg_mask & IXL_DBG_SWITCH_INFO) { device_printf(dev, "Switch config: header reported: %d in structure, %d total\n", - sw_config->header.num_reported, sw_config->header.num_total); - for (int i = 0; i < sw_config->header.num_reported; i++) { + LE16_TO_CPU(sw_config->header.num_reported), + LE16_TO_CPU(sw_config->header.num_total)); + for (int i = 0; + i < LE16_TO_CPU(sw_config->header.num_reported); i++) { device_printf(dev, "-> %d: type=%d seid=%d uplink=%d downlink=%d\n", i, sw_config->element[i].element_type, - sw_config->element[i].seid, - sw_config->element[i].uplink_seid, - sw_config->element[i].downlink_seid); + LE16_TO_CPU(sw_config->element[i].seid), + LE16_TO_CPU(sw_config->element[i].uplink_seid), + LE16_TO_CPU(sw_config->element[i].downlink_seid)); } } /* Simplified due to a single VSI */ - vsi->uplink_seid = sw_config->element[0].uplink_seid; - vsi->downlink_seid = sw_config->element[0].downlink_seid; - vsi->seid = sw_config->element[0].seid; + vsi->uplink_seid = LE16_TO_CPU(sw_config->element[0].uplink_seid); + vsi->downlink_seid = LE16_TO_CPU(sw_config->element[0].downlink_seid); + vsi->seid = LE16_TO_CPU(sw_config->element[0].seid); return (ret); } @@ -2058,12 +2060,14 @@ ixl_add_hw_filters(struct ixl_vsi *vsi, int flags, int cnt) bcopy(f->macaddr, b->mac_addr, ETHER_ADDR_LEN); if (f->vlan == IXL_VLAN_ANY) { b->vlan_tag = 0; - b->flags = I40E_AQC_MACVLAN_ADD_IGNORE_VLAN; + b->flags = CPU_TO_LE16( + I40E_AQC_MACVLAN_ADD_IGNORE_VLAN); } else { - b->vlan_tag = f->vlan; + b->vlan_tag = CPU_TO_LE16(f->vlan); b->flags = 0; } - b->flags |= I40E_AQC_MACVLAN_ADD_PERFECT_MATCH; + b->flags |= CPU_TO_LE16( + I40E_AQC_MACVLAN_ADD_PERFECT_MATCH); f->flags &= ~IXL_FILTER_ADD; j++; From db724d9005181a8511f9be0d5e0c15f2cf1c98ba Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Fri, 6 Mar 2020 14:46:50 +0000 Subject: [PATCH 15/19] Update the hypervisor registers - Add more registers needed by bhyve [1] - Move EL2 registers from armreg.h to hypervisor.h - Add the register name to hypervisor.h Obtained from: https://github.com/FreeBSD-UPB/freebsd [1] --- sys/arm64/include/armreg.h | 11 ---- sys/arm64/include/hypervisor.h | 107 ++++++++++++++++++++++++++++++--- 2 files changed, 98 insertions(+), 20 deletions(-) diff --git a/sys/arm64/include/armreg.h b/sys/arm64/include/armreg.h index b2a201119fe3..7e171e561649 100644 --- a/sys/arm64/include/armreg.h +++ b/sys/arm64/include/armreg.h @@ -66,13 +66,6 @@ #define UL(x) UINT64_C(x) -/* CNTHCTL_EL2 - Counter-timer Hypervisor Control register */ -#define CNTHCTL_EVNTI_MASK (0xf << 4) /* Bit to trigger event stream */ -#define CNTHCTL_EVNTDIR (1 << 3) /* Control transition trigger bit */ -#define CNTHCTL_EVNTEN (1 << 2) /* Enable event stream */ -#define CNTHCTL_EL1PCEN (1 << 1) /* Allow EL0/1 physical timer access */ -#define CNTHCTL_EL1PCTEN (1 << 0) /*Allow EL0/1 physical counter access*/ - /* CPACR_EL1 */ #define CPACR_FPEN_MASK (0x3 << 20) #define CPACR_FPEN_TRAP_ALL1 (0x0 << 20) /* Traps from EL0 and EL1 */ @@ -220,10 +213,6 @@ /* ICC_SRE_EL1 */ #define ICC_SRE_EL1_SRE (1U << 0) -/* ICC_SRE_EL2 */ -#define ICC_SRE_EL2_SRE (1U << 0) -#define ICC_SRE_EL2_EN (1U << 3) - /* ID_AA64DFR0_EL1 */ #define ID_AA64DFR0_EL1 MRS_REG(3, 0, 0, 5, 0) #define ID_AA64DFR0_DebugVer_SHIFT 0 diff --git a/sys/arm64/include/hypervisor.h b/sys/arm64/include/hypervisor.h index 7ac0069af1be..eab43b29a89e 100644 --- a/sys/arm64/include/hypervisor.h +++ b/sys/arm64/include/hypervisor.h @@ -34,19 +34,21 @@ * e.g. specific to EL2, or controlling the hypervisor. */ -/* - * Architecture feature trap register - */ +/* CNTHCTL_EL2 - Counter-timer Hypervisor Control register */ +#define CNTHCTL_EVNTI_MASK (0xf << 4) /* Bit to trigger event stream */ +#define CNTHCTL_EVNTDIR (1 << 3) /* Control transition trigger bit */ +#define CNTHCTL_EVNTEN (1 << 2) /* Enable event stream */ +#define CNTHCTL_EL1PCEN (1 << 1) /* Allow EL0/1 physical timer access */ +#define CNTHCTL_EL1PCTEN (1 << 0) /*Allow EL0/1 physical counter access*/ + +/* CPTR_EL2 - Architecture feature trap register */ #define CPTR_RES0 0x7fefc800 #define CPTR_RES1 0x000033ff #define CPTR_TFP 0x00000400 #define CPTR_TTA 0x00100000 #define CPTR_TCPAC 0x80000000 -/* - * Hypervisor Config Register - */ - +/* HCR_EL2 - Hypervisor Config Register */ #define HCR_VM 0x0000000000000001 #define HCR_SWIO 0x0000000000000002 #define HCR_PTW 0x0000000000000004 @@ -58,6 +60,9 @@ #define HCR_VSE 0x0000000000000100 #define HCR_FB 0x0000000000000200 #define HCR_BSU_MASK 0x0000000000000c00 +#define HCR_BSU_IS 0x0000000000000400 +#define HCR_BSU_OS 0x0000000000000800 +#define HCR_BSU_FS 0x0000000000000c00 #define HCR_DC 0x0000000000001000 #define HCR_TWI 0x0000000000002000 #define HCR_TWE 0x0000000000004000 @@ -69,7 +74,7 @@ #define HCR_TIDCP 0x0000000000100000 #define HCR_TACR 0x0000000000200000 #define HCR_TSW 0x0000000000400000 -#define HCR_TPC 0x0000000000800000 +#define HCR_TPCP 0x0000000000800000 #define HCR_TPU 0x0000000001000000 #define HCR_TTLB 0x0000000002000000 #define HCR_TVM 0x0000000004000000 @@ -92,5 +97,89 @@ #define HCR_NV1 0x0000080000000000 #define HCR_AT 0x0000100000000000 -#endif +/* HPFAR_EL2 - Hypervisor IPA Fault Address Register */ +#define HPFAR_EL2_FIPA_SHIFT 4 +#define HPFAR_EL2_FIPA_MASK 0xfffffffff0 +/* ICC_SRE_EL2 */ +#define ICC_SRE_EL2_SRE (1U << 0) +#define ICC_SRE_EL2_EN (1U << 3) + +/* SCTLR_EL2 - System Control Register */ +#define SCTLR_EL2_RES1 0x30c50830 +#define SCTLR_EL2_M_SHIFT 0 +#define SCTLR_EL2_M (0x1 << SCTLR_EL2_M_SHIFT) +#define SCTLR_EL2_A_SHIFT 1 +#define SCTLR_EL2_A (0x1 << SCTLR_EL2_A_SHIFT) +#define SCTLR_EL2_C_SHIFT 2 +#define SCTLR_EL2_C (0x1 << SCTLR_EL2_C_SHIFT) +#define SCTLR_EL2_SA_SHIFT 3 +#define SCTLR_EL2_SA (0x1 << SCTLR_EL2_SA_SHIFT) +#define SCTLR_EL2_I_SHIFT 12 +#define SCTLR_EL2_I (0x1 << SCTLR_EL2_I_SHIFT) +#define SCTLR_EL2_WXN_SHIFT 19 +#define SCTLR_EL2_WXN (0x1 << SCTLR_EL2_WXN_SHIFT) +#define SCTLR_EL2_EE_SHIFT 25 +#define SCTLR_EL2_EE (0x1 << SCTLR_EL2_EE_SHIFT) + +/* TCR_EL2 - Translation Control Register */ +#define TCR_EL2_RES1 ((0x1UL << 31) | (0x1UL << 23)) +#define TCR_EL2_T0SZ_SHIFT 0 +#define TCR_EL2_T0SZ_MASK (0x3f << TCR_EL2_T0SZ_SHIFT) +#define TCR_EL2_T0SZ(x) ((x) << TCR_EL2_T0SZ_SHIFT) +/* Bits 7:6 are reserved */ +#define TCR_EL2_IRGN0_SHIFT 8 +#define TCR_EL2_IRGN0_MASK (0x3 << TCR_EL2_IRGN0_SHIFT) +#define TCR_EL2_ORGN0_SHIFT 10 +#define TCR_EL2_ORGN0_MASK (0x3 << TCR_EL2_ORGN0_SHIFT) +#define TCR_EL2_SH0_SHIFT 12 +#define TCR_EL2_SH0_MASK (0x3 << TCR_EL2_SH0_SHIFT) +#define TCR_EL2_TG0_SHIFT 14 +#define TCR_EL2_TG0_MASK (0x3 << TCR_EL2_TG0_SHIFT) +#define TCR_EL2_PS_SHIFT 16 +#define TCR_EL2_PS_32BITS (0 << TCR_EL2_PS_SHIFT) +#define TCR_EL2_PS_36BITS (1 << TCR_EL2_PS_SHIFT) +#define TCR_EL2_PS_40BITS (2 << TCR_EL2_PS_SHIFT) +#define TCR_EL2_PS_42BITS (3 << TCR_EL2_PS_SHIFT) +#define TCR_EL2_PS_44BITS (4 << TCR_EL2_PS_SHIFT) +#define TCR_EL2_PS_48BITS (5 << TCR_EL2_PS_SHIFT) +#define TCR_EL2_PS_52BITS (6 << TCR_EL2_PS_SHIFT) /* ARMv8.2-LPA */ + +/* VMPDIR_EL2 - Virtualization Multiprocessor ID Register */ +#define VMPIDR_EL2_U 0x0000000040000000 +#define VMPIDR_EL2_MT 0x0000000001000000 +#define VMPIDR_EL2_RES1 0x0000000080000000 + +/* VTCR_EL2 - Virtualization Translation Control Register */ +#define VTCR_EL2_RES1 (0x1 << 31) +#define VTCR_EL2_T0SZ_MASK 0x3f +#define VTCR_EL2_SL0_SHIFT 6 +#define VTCR_EL2_SL0_4K_LVL2 (0x0 << VTCR_EL2_SL0_SHIFT) +#define VTCR_EL2_SL0_4K_LVL1 (0x1 << VTCR_EL2_SL0_SHIFT) +#define VTCR_EL2_SL0_4K_LVL0 (0x2 << VTCR_EL2_SL0_SHIFT) +#define VTCR_EL2_IRGN0_SHIFT 8 +#define VTCR_EL2_IRGN0_WBWA (0x1 << VTCR_EL2_IRGN0_SHIFT) +#define VTCR_EL2_ORGN0_SHIFT 10 +#define VTCR_EL2_ORGN0_WBWA (0x1 << VTCR_EL2_ORGN0_SHIFT) +#define VTCR_EL2_SH0_SHIFT 12 +#define VTCR_EL2_SH0_NS (0x0 << VTCR_EL2_SH0_SHIFT) +#define VTCR_EL2_SH0_OS (0x2 << VTCR_EL2_SH0_SHIFT) +#define VTCR_EL2_SH0_IS (0x3 << VTCR_EL2_SH0_SHIFT) +#define VTCR_EL2_TG0_SHIFT 14 +#define VTCR_EL2_TG0_4K (0x0 << VTCR_EL2_TG0_SHIFT) +#define VTCR_EL2_TG0_64K (0x1 << VTCR_EL2_TG0_SHIFT) +#define VTCR_EL2_TG0_16K (0x2 << VTCR_EL2_TG0_SHIFT) +#define VTCR_EL2_PS_SHIFT 16 +#define VTCR_EL2_PS_32BIT (0x0 << VTCR_EL2_PS_SHIFT) +#define VTCR_EL2_PS_36BIT (0x1 << VTCR_EL2_PS_SHIFT) +#define VTCR_EL2_PS_40BIT (0x2 << VTCR_EL2_PS_SHIFT) +#define VTCR_EL2_PS_42BIT (0x3 << VTCR_EL2_PS_SHIFT) +#define VTCR_EL2_PS_44BIT (0x4 << VTCR_EL2_PS_SHIFT) +#define VTCR_EL2_PS_48BIT (0x5 << VTCR_EL2_PS_SHIFT) + +/* VTTBR_EL2 - Virtualization Translation Table Base Register */ +#define VTTBR_VMID_MASK 0xffff000000000000 +#define VTTBR_VMID_SHIFT 48 +#define VTTBR_HOST 0x0000000000000000 + +#endif /* !_MACHINE_HYPERVISOR_H_ */ From 4d8a9faf17bb538173a36190aa57620b0de252e2 Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Fri, 6 Mar 2020 15:26:15 +0000 Subject: [PATCH 16/19] readelf: add XEN_ELFNOTE_PHYS32_ENTRY note See r336469 for details. Sponsored by: The FreeBSD Foundation --- contrib/elftoolchain/readelf/readelf.c | 1 + 1 file changed, 1 insertion(+) diff --git a/contrib/elftoolchain/readelf/readelf.c b/contrib/elftoolchain/readelf/readelf.c index 8814f235ce1b..574a5c9453d3 100644 --- a/contrib/elftoolchain/readelf/readelf.c +++ b/contrib/elftoolchain/readelf/readelf.c @@ -1283,6 +1283,7 @@ note_type_xen(unsigned int nt) case 15: return "XEN_ELFNOTE_INIT_P2M"; case 16: return "XEN_ELFNOTE_MOD_START_PFN"; case 17: return "XEN_ELFNOTE_SUPPORTED_FEATURES"; + case 18: return "XEN_ELFNOTE_PHYS32_ENTRY"; default: return (note_type_unknown(nt)); } } From ff0f134bb11be1ad3d43e718bbf58ea481020348 Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Fri, 6 Mar 2020 15:58:52 +0000 Subject: [PATCH 17/19] readelf: decode and print Xen ELF note strings Sponsored by: The FreeBSD Foundation --- contrib/elftoolchain/readelf/readelf.c | 51 ++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/contrib/elftoolchain/readelf/readelf.c b/contrib/elftoolchain/readelf/readelf.c index 574a5c9453d3..e5a6fa0de2e6 100644 --- a/contrib/elftoolchain/readelf/readelf.c +++ b/contrib/elftoolchain/readelf/readelf.c @@ -3676,6 +3676,33 @@ static struct flag_desc note_feature_ctl_flags[] = { { 0, NULL } }; +static void +dump_note_string(const char *description, const char *s, size_t len) +{ + size_t i; + int printable = 1; + + if (len == 0 || s[--len] != '\0') { + printable = 0; + } else { + for (i = 0; i < len; i++) { + if (!isprint(s[i])) { + printable = 0; + break; + } + } + } + + if (printable) { + printf(" %s: %s\n", description, s); + } else { + printf(" description data:"); + for (i = 0; i < len; i++) + printf(" %02x", (unsigned char)s[i]); + printf("\n"); + } +} + static void dump_notes_data(struct readelf *re, const char *name, uint32_t type, const char *buf, size_t sz) @@ -3716,6 +3743,30 @@ dump_notes_data(struct readelf *re, const char *name, uint32_t type, dump_gnu_property_type_0(re, buf, sz); return; } + } else if (strcmp(name, "Xen") == 0) { + switch (type) { + case 5: + dump_note_string("Xen version", buf, sz); + return; + case 6: + dump_note_string("Guest OS", buf, sz); + return; + case 7: + dump_note_string("Guest version", buf, sz); + return; + case 8: + dump_note_string("Loader", buf, sz); + return; + case 9: + dump_note_string("PAE mode", buf, sz); + return; + case 10: + dump_note_string("Features", buf, sz); + return; + case 11: + dump_note_string("BSD symtab", buf, sz); + return; + } } unknown: printf(" description data:"); From 3a1c1a303e9fa35e1b4e3d020b4088349941ff29 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Fri, 6 Mar 2020 16:00:35 +0000 Subject: [PATCH 18/19] Add more are64 special register fields Obtained from: https://github.com/FreeBSD-UPB/freebsd --- sys/arm64/include/armreg.h | 60 ++++++++++++++++++++++++++++++++++---- 1 file changed, 54 insertions(+), 6 deletions(-) diff --git a/sys/arm64/include/armreg.h b/sys/arm64/include/armreg.h index 7e171e561649..338106c9dec6 100644 --- a/sys/arm64/include/armreg.h +++ b/sys/arm64/include/armreg.h @@ -66,6 +66,18 @@ #define UL(x) UINT64_C(x) +/* CNTHCTL_EL2 - Counter-timer Hypervisor Control register */ +#define CNTHCTL_EVNTI_MASK (0xf << 4) /* Bit to trigger event stream */ +#define CNTHCTL_EVNTDIR (1 << 3) /* Control transition trigger bit */ +#define CNTHCTL_EVNTEN (1 << 2) /* Enable event stream */ +#define CNTHCTL_EL1PCEN (1 << 1) /* Allow EL0/1 physical timer access */ +#define CNTHCTL_EL1PCTEN (1 << 0) /*Allow EL0/1 physical counter access*/ + +/* CNTP_CTL_EL0 - Counter-timer Physical Timer Control register */ +#define CNTP_CTL_ENABLE (1 << 0) +#define CNTP_CTL_IMASK (1 << 1) +#define CNTP_CTL_ISTATUS (1 << 2) + /* CPACR_EL1 */ #define CPACR_FPEN_MASK (0x3 << 20) #define CPACR_FPEN_TRAP_ALL1 (0x0 << 20) /* Traps from EL0 and EL1 */ @@ -122,22 +134,53 @@ #define DCZID_BS_SIZE(reg) (((reg) & DCZID_BS_MASK) >> DCZID_BS_SHIFT) /* ESR_ELx */ -#define ESR_ELx_ISS_MASK 0x00ffffff +#define ESR_ELx_ISS_MASK 0x01ffffff #define ISS_INSN_FnV (0x01 << 10) #define ISS_INSN_EA (0x01 << 9) #define ISS_INSN_S1PTW (0x01 << 7) #define ISS_INSN_IFSC_MASK (0x1f << 0) -#define ISS_DATA_ISV (0x01 << 24) -#define ISS_DATA_SAS_MASK (0x03 << 22) -#define ISS_DATA_SSE (0x01 << 21) -#define ISS_DATA_SRT_MASK (0x1f << 16) + +#define ISS_MSR_DIR_SHIFT 0 +#define ISS_MSR_DIR (0x01 << ISS_MSR_DIR_SHIFT) +#define ISS_MSR_Rt_SHIFT 5 +#define ISS_MSR_Rt_MASK (0x1f << ISS_MSR_Rt_SHIFT) +#define ISS_MSR_Rt(x) (((x) & ISS_MSR_Rt_MASK) >> ISS_MSR_Rt_SHIFT) +#define ISS_MSR_CRm_SHIFT 1 +#define ISS_MSR_CRm_MASK (0xf << ISS_MSR_CRm_SHIFT) +#define ISS_MSR_CRm(x) (((x) & ISS_MSR_CRm_MASK) >> ISS_MSR_CRm_SHIFT) +#define ISS_MSR_CRn_SHIFT 10 +#define ISS_MSR_CRn_MASK (0xf << ISS_MSR_CRn_SHIFT) +#define ISS_MSR_CRn(x) (((x) & ISS_MSR_CRn_MASK) >> ISS_MSR_CRn_SHIFT) +#define ISS_MSR_OP1_SHIFT 14 +#define ISS_MSR_OP1_MASK (0x7 << ISS_MSR_OP1_SHIFT) +#define ISS_MSR_OP1(x) (((x) & ISS_MSR_OP1_MASK) >> ISS_MSR_OP1_SHIFT) +#define ISS_MSR_OP2_SHIFT 17 +#define ISS_MSR_OP2_MASK (0x7 << ISS_MSR_OP2_SHIFT) +#define ISS_MSR_OP2(x) (((x) & ISS_MSR_OP2_MASK) >> ISS_MSR_OP2_SHIFT) +#define ISS_MSR_OP0_SHIFT 20 +#define ISS_MSR_OP0_MASK (0x3 << ISS_MSR_OP0_SHIFT) +#define ISS_MSR_OP0(x) (((x) & ISS_MSR_OP0_MASK) >> ISS_MSR_OP0_SHIFT) +#define ISS_MSR_REG_MASK \ + (ISS_MSR_OP0_MASK | ISS_MSR_OP2_MASK | ISS_MSR_OP1_MASK | \ + ISS_MSR_CRn_MASK | ISS_MSR_CRm_MASK) + + +#define ISS_DATA_ISV_SHIFT 24 +#define ISS_DATA_ISV (0x01 << ISS_DATA_ISV_SHIFT) +#define ISS_DATA_SAS_SHIFT 22 +#define ISS_DATA_SAS_MASK (0x03 << ISS_DATA_SAS_SHIFT) +#define ISS_DATA_SSE_SHIFT 21 +#define ISS_DATA_SSE (0x01 << ISS_DATA_SSE_SHIFT) +#define ISS_DATA_SRT_SHIFT 16 +#define ISS_DATA_SRT_MASK (0x1f << ISS_DATA_SRT_SHIFT) #define ISS_DATA_SF (0x01 << 15) #define ISS_DATA_AR (0x01 << 14) #define ISS_DATA_FnV (0x01 << 10) #define ISS_DATA_EA (0x01 << 9) #define ISS_DATA_CM (0x01 << 8) #define ISS_DATA_S1PTW (0x01 << 7) -#define ISS_DATA_WnR (0x01 << 6) +#define ISS_DATA_WnR_SHIFT 6 +#define ISS_DATA_WnR (0x01 << ISS_DATA_WnR_SHIFT) #define ISS_DATA_DFSC_MASK (0x3f << 0) #define ISS_DATA_DFSC_ASF_L0 (0x00 << 0) #define ISS_DATA_DFSC_ASF_L1 (0x01 << 0) @@ -170,10 +213,12 @@ #define ESR_ELx_EC_MASK (0x3f << 26) #define ESR_ELx_EXCEPTION(esr) (((esr) & ESR_ELx_EC_MASK) >> ESR_ELx_EC_SHIFT) #define EXCP_UNKNOWN 0x00 /* Unkwn exception */ +#define EXCP_TRAP_WFI_WFE 0x01 /* Trapped WFI or WFE */ #define EXCP_FP_SIMD 0x07 /* VFP/SIMD trap */ #define EXCP_ILL_STATE 0x0e /* Illegal execution state */ #define EXCP_SVC32 0x11 /* SVC trap for AArch32 */ #define EXCP_SVC64 0x15 /* SVC trap for AArch64 */ +#define EXCP_HVC 0x16 /* HVC trap */ #define EXCP_MSR 0x18 /* MSR/MRS trap */ #define EXCP_INSN_ABORT_L 0x20 /* Instruction abort, from lower EL */ #define EXCP_INSN_ABORT 0x21 /* Instruction abort, from same EL */ @@ -714,6 +759,8 @@ #define TCR_TG1_4K (2 << TCR_TG1_SHIFT) #define TCR_TG1_64K (3 << TCR_TG1_SHIFT) +#define TCR_TG0_MASK 0x000000000000c000 + #define TCR_SH1_SHIFT 28 #define TCR_SH1_IS (0x3UL << TCR_SH1_SHIFT) #define TCR_ORGN1_SHIFT 26 @@ -740,6 +787,7 @@ #define TCR_T1SZ_SHIFT 16 #define TCR_T0SZ_SHIFT 0 +#define TCR_T0SZ_MASK 0x3f #define TCR_T1SZ(x) ((x) << TCR_T1SZ_SHIFT) #define TCR_T0SZ(x) ((x) << TCR_T0SZ_SHIFT) #define TCR_TxSZ(x) (TCR_T1SZ(x) | TCR_T0SZ(x)) From fc7efa1b6a45b6407d170ce150a1cec1594c4018 Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Fri, 6 Mar 2020 17:02:14 +0000 Subject: [PATCH 19/19] Merge commit f75939599 from llvm git (by Erich Keane): Reland r374450 with Richard Smith's comments and test fixed. The behavior from the original patch has changed, since we're no longer allowing LLVM to just ignore the alignment. Instead, we're just assuming the maximum possible alignment. Differential Revision: https://reviews.llvm.org/D68824 llvm-svn: 374562 This fixes 'Assertion failed: (Alignment != 0 && "Invalid Alignment"), function CreateAlignmentAssumption', when building recent versions of v8, which invoke __builtin_assume_aligned() with its alignment argument set to 4GiB or more. Clang will now report a warning, and show the maximum possible alignment instead, e.g.: huge-align.cpp:1:27: warning: requested alignment must be 536870912 bytes or smaller; maximum alignment assumed [-Wbuiltin-assume-aligned-alignment] void *f(void *g) { return __builtin_assume_aligned(g, 4294967296); } ^ ~~~~~~~~~~ Upstream PR: https://bugs.llvm.org/show_bug.cgi?id=43839 Reported by: cem MFC after: 3 days --- .../include/clang/Basic/DiagnosticSemaKinds.td | 4 ++++ .../clang/lib/CodeGen/CGBuiltin.cpp | 6 ++++-- .../llvm-project/clang/lib/CodeGen/CGCall.cpp | 2 +- .../clang/lib/CodeGen/CGExprScalar.cpp | 3 +-- .../clang/lib/CodeGen/CGStmtOpenMP.cpp | 11 ++++++----- .../clang/lib/CodeGen/CodeGenFunction.cpp | 17 +---------------- .../clang/lib/CodeGen/CodeGenFunction.h | 7 +------ .../clang/lib/Sema/SemaChecking.cpp | 6 ++++++ 8 files changed, 24 insertions(+), 32 deletions(-) diff --git a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticSemaKinds.td b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticSemaKinds.td index 275c4e4365d1..0d855ad8da7e 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -2797,6 +2797,10 @@ def err_alignment_dependent_typedef_name : Error< def err_attribute_aligned_too_great : Error< "requested alignment must be %0 bytes or smaller">; +def warn_assume_aligned_too_great + : Warning<"requested alignment must be %0 bytes or smaller; maximum " + "alignment assumed">, + InGroup>; def warn_redeclaration_without_attribute_prev_attribute_ignored : Warning< "%q0 redeclared without %1 attribute: previous %1 ignored">, InGroup; diff --git a/contrib/llvm-project/clang/lib/CodeGen/CGBuiltin.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGBuiltin.cpp index cadce507412b..dca531d296b4 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CGBuiltin.cpp +++ b/contrib/llvm-project/clang/lib/CodeGen/CGBuiltin.cpp @@ -2026,11 +2026,13 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, Value *AlignmentValue = EmitScalarExpr(E->getArg(1)); ConstantInt *AlignmentCI = cast(AlignmentValue); - unsigned Alignment = (unsigned)AlignmentCI->getZExtValue(); + if (AlignmentCI->getValue().ugt(llvm::Value::MaximumAlignment)) + AlignmentCI = ConstantInt::get(AlignmentCI->getType(), + llvm::Value::MaximumAlignment); EmitAlignmentAssumption(PtrValue, Ptr, /*The expr loc is sufficient.*/ SourceLocation(), - Alignment, OffsetValue); + AlignmentCI, OffsetValue); return RValue::get(PtrValue); } case Builtin::BI__assume: diff --git a/contrib/llvm-project/clang/lib/CodeGen/CGCall.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGCall.cpp index cf8024550eee..125adbab106b 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CGCall.cpp +++ b/contrib/llvm-project/clang/lib/CodeGen/CGCall.cpp @@ -4548,7 +4548,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, llvm::Value *Alignment = EmitScalarExpr(AA->getAlignment()); llvm::ConstantInt *AlignmentCI = cast(Alignment); EmitAlignmentAssumption(Ret.getScalarVal(), RetTy, Loc, AA->getLocation(), - AlignmentCI->getZExtValue(), OffsetValue); + AlignmentCI, OffsetValue); } else if (const auto *AA = TargetDecl->getAttr()) { llvm::Value *AlignmentVal = CallArgs[AA->getParamIndex().getLLVMIndex()] .getRValue(*this) diff --git a/contrib/llvm-project/clang/lib/CodeGen/CGExprScalar.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGExprScalar.cpp index 3d082de2a14f..44de87f2bb4a 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CGExprScalar.cpp +++ b/contrib/llvm-project/clang/lib/CodeGen/CGExprScalar.cpp @@ -294,8 +294,7 @@ class ScalarExprEmitter Value *AlignmentValue = CGF.EmitScalarExpr(AVAttr->getAlignment()); llvm::ConstantInt *AlignmentCI = cast(AlignmentValue); - CGF.EmitAlignmentAssumption(V, E, AVAttr->getLocation(), - AlignmentCI->getZExtValue()); + CGF.EmitAlignmentAssumption(V, E, AVAttr->getLocation(), AlignmentCI); } /// EmitLoadOfLValue - Given an expression with complex type that represents a diff --git a/contrib/llvm-project/clang/lib/CodeGen/CGStmtOpenMP.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGStmtOpenMP.cpp index e8fbca5108ad..67f0b3ad16de 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/contrib/llvm-project/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -1460,14 +1460,14 @@ static void emitAlignedClause(CodeGenFunction &CGF, if (!CGF.HaveInsertPoint()) return; for (const auto *Clause : D.getClausesOfKind()) { - unsigned ClauseAlignment = 0; + llvm::APInt ClauseAlignment(64, 0); if (const Expr *AlignmentExpr = Clause->getAlignment()) { auto *AlignmentCI = cast(CGF.EmitScalarExpr(AlignmentExpr)); - ClauseAlignment = static_cast(AlignmentCI->getZExtValue()); + ClauseAlignment = AlignmentCI->getValue(); } for (const Expr *E : Clause->varlists()) { - unsigned Alignment = ClauseAlignment; + llvm::APInt Alignment(ClauseAlignment); if (Alignment == 0) { // OpenMP [2.8.1, Description] // If no optional parameter is specified, implementation-defined default @@ -1478,12 +1478,13 @@ static void emitAlignedClause(CodeGenFunction &CGF, E->getType()->getPointeeType())) .getQuantity(); } - assert((Alignment == 0 || llvm::isPowerOf2_32(Alignment)) && + assert((Alignment == 0 || Alignment.isPowerOf2()) && "alignment is not power of 2"); if (Alignment != 0) { llvm::Value *PtrValue = CGF.EmitScalarExpr(E); CGF.EmitAlignmentAssumption( - PtrValue, E, /*No second loc needed*/ SourceLocation(), Alignment); + PtrValue, E, /*No second loc needed*/ SourceLocation(), + llvm::ConstantInt::get(CGF.getLLVMContext(), Alignment)); } } } diff --git a/contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp b/contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp index eafe26674434..2b058aea53cd 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp @@ -2047,25 +2047,10 @@ void CodeGenFunction::EmitAlignmentAssumption(llvm::Value *PtrValue, } } -void CodeGenFunction::EmitAlignmentAssumption(llvm::Value *PtrValue, - QualType Ty, SourceLocation Loc, - SourceLocation AssumptionLoc, - unsigned Alignment, - llvm::Value *OffsetValue) { - llvm::Value *TheCheck; - llvm::Instruction *Assumption = Builder.CreateAlignmentAssumption( - CGM.getDataLayout(), PtrValue, Alignment, OffsetValue, &TheCheck); - if (SanOpts.has(SanitizerKind::Alignment)) { - llvm::Value *AlignmentVal = llvm::ConstantInt::get(IntPtrTy, Alignment); - EmitAlignmentAssumptionCheck(PtrValue, Ty, Loc, AssumptionLoc, AlignmentVal, - OffsetValue, TheCheck, Assumption); - } -} - void CodeGenFunction::EmitAlignmentAssumption(llvm::Value *PtrValue, const Expr *E, SourceLocation AssumptionLoc, - unsigned Alignment, + llvm::Value *Alignment, llvm::Value *OffsetValue) { if (auto *CE = dyn_cast(E)) E = CE->getSubExprAsWritten(); diff --git a/contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.h b/contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.h index c3060d1fb351..65a3ee55552a 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.h +++ b/contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.h @@ -2829,13 +2829,8 @@ class CodeGenFunction : public CodeGenTypeCache { llvm::Value *Alignment, llvm::Value *OffsetValue = nullptr); - void EmitAlignmentAssumption(llvm::Value *PtrValue, QualType Ty, - SourceLocation Loc, SourceLocation AssumptionLoc, - unsigned Alignment, - llvm::Value *OffsetValue = nullptr); - void EmitAlignmentAssumption(llvm::Value *PtrValue, const Expr *E, - SourceLocation AssumptionLoc, unsigned Alignment, + SourceLocation AssumptionLoc, llvm::Value *Alignment, llvm::Value *OffsetValue = nullptr); //===--------------------------------------------------------------------===// diff --git a/contrib/llvm-project/clang/lib/Sema/SemaChecking.cpp b/contrib/llvm-project/clang/lib/Sema/SemaChecking.cpp index f9f82cdeef43..9205be8c7319 100644 --- a/contrib/llvm-project/clang/lib/Sema/SemaChecking.cpp +++ b/contrib/llvm-project/clang/lib/Sema/SemaChecking.cpp @@ -5961,6 +5961,12 @@ bool Sema::SemaBuiltinAssumeAligned(CallExpr *TheCall) { if (!Result.isPowerOf2()) return Diag(TheCall->getBeginLoc(), diag::err_alignment_not_power_of_two) << Arg->getSourceRange(); + + // Alignment calculations can wrap around if it's greater than 2**29. + unsigned MaximumAlignment = 536870912; + if (Result > MaximumAlignment) + Diag(TheCall->getBeginLoc(), diag::warn_assume_aligned_too_great) + << Arg->getSourceRange() << MaximumAlignment; } if (NumArgs > 2) {