MFC- tracking commit.
This commit is contained in:
commit
586f9f8f2e
@ -481,7 +481,6 @@ main(int argc, char **argv)
|
||||
* We skip P_SYSTEM processes to match ps(1) output.
|
||||
*/
|
||||
if ((kp->ki_flag & P_SYSTEM) == 0 &&
|
||||
kp->ki_loginclass != NULL &&
|
||||
strcmp(kp->ki_loginclass, li->li_name) == 0)
|
||||
break;
|
||||
}
|
||||
|
@ -129,7 +129,7 @@ Set to not build
|
||||
.Xr authpf 8 .
|
||||
.It Va WITHOUT_BINUTILS
|
||||
.\" from FreeBSD: head/tools/build/options/WITHOUT_BINUTILS 255974 2013-10-01 17:40:56Z emaste
|
||||
Set to not install binutils (as, c++-filt, gconv,
|
||||
Set to not install binutils (as, c++-filt, gconv,
|
||||
ld, nm, objcopy, objdump, readelf, size and strip).
|
||||
.Bf -symbolic
|
||||
The option does not generally work for build targets, unless some alternative
|
||||
|
@ -503,6 +503,7 @@ device asmc
|
||||
device tpm
|
||||
device padlock_rng # VIA Padlock RNG
|
||||
device rdrand_rng # Intel Bull Mountain RNG
|
||||
device aesni # AES-NI OpenCrypto module
|
||||
|
||||
#
|
||||
# Laptop/Notebook options:
|
||||
|
@ -1255,7 +1255,7 @@ cfiscsi_init(void)
|
||||
|
||||
cfiscsi_data_wait_zone = uma_zcreate("cfiscsi_data_wait",
|
||||
sizeof(struct cfiscsi_data_wait), NULL, NULL, NULL, NULL,
|
||||
UMA_ALIGN_PTR, UMA_ZONE_NOFREE);
|
||||
UMA_ALIGN_PTR, 0);
|
||||
|
||||
return (0);
|
||||
|
||||
|
@ -175,6 +175,7 @@ struct stat32 {
|
||||
u_int32_t st_blksize;
|
||||
u_int32_t st_flags;
|
||||
u_int32_t st_gen;
|
||||
int32_t st_lspare;
|
||||
struct timespec32 st_birthtim;
|
||||
unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec32));
|
||||
unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec32));
|
||||
|
@ -957,6 +957,7 @@ icl_pdu_queue(struct icl_pdu *ip)
|
||||
if (ic->ic_disconnecting || ic->ic_socket == NULL) {
|
||||
ICL_DEBUG("icl_pdu_queue on closed connection");
|
||||
ICL_CONN_UNLOCK(ic);
|
||||
icl_pdu_free(ip);
|
||||
return;
|
||||
}
|
||||
TAILQ_INSERT_TAIL(&ic->ic_to_send, ip, ip_next);
|
||||
@ -1259,10 +1260,10 @@ icl_load(void)
|
||||
|
||||
icl_conn_zone = uma_zcreate("icl_conn",
|
||||
sizeof(struct icl_conn), NULL, NULL, NULL, NULL,
|
||||
UMA_ALIGN_PTR, UMA_ZONE_NOFREE);
|
||||
UMA_ALIGN_PTR, 0);
|
||||
icl_pdu_zone = uma_zcreate("icl_pdu",
|
||||
sizeof(struct icl_pdu), NULL, NULL, NULL, NULL,
|
||||
UMA_ALIGN_PTR, UMA_ZONE_NOFREE);
|
||||
UMA_ALIGN_PTR, 0);
|
||||
|
||||
refcount_init(&icl_ncons, 0);
|
||||
}
|
||||
|
@ -2030,7 +2030,7 @@ iscsi_load(void)
|
||||
|
||||
iscsi_outstanding_zone = uma_zcreate("iscsi_outstanding",
|
||||
sizeof(struct iscsi_outstanding), NULL, NULL, NULL, NULL,
|
||||
UMA_ALIGN_PTR, UMA_ZONE_NOFREE);
|
||||
UMA_ALIGN_PTR, 0);
|
||||
|
||||
error = make_dev_p(MAKEDEV_CHECKNAME, &sc->sc_cdev, &iscsi_cdevsw,
|
||||
NULL, UID_ROOT, GID_WHEEL, 0600, "iscsi");
|
||||
|
@ -857,6 +857,7 @@ device asmc
|
||||
device tpm
|
||||
device padlock_rng # VIA Padlock RNG
|
||||
device rdrand_rng # Intel Bull Mountain RNG
|
||||
device aesni # AES-NI OpenCrypto module
|
||||
|
||||
#
|
||||
# Laptop/Notebook options:
|
||||
|
@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/systm.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/endian.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/module.h>
|
||||
@ -62,14 +63,14 @@ __FBSDID("$FreeBSD$");
|
||||
#include <mips/nlm/hal/sys.h>
|
||||
#include <mips/nlm/hal/fmn.h>
|
||||
#include <mips/nlm/hal/nlmsaelib.h>
|
||||
#include <mips/nlm/dev/sec/nlmrsalib.h>
|
||||
#include <mips/nlm/dev/sec/rsa_ucode.h>
|
||||
#include <mips/nlm/hal/cop2.h>
|
||||
#include <mips/nlm/hal/mips-extns.h>
|
||||
#include <mips/nlm/msgring.h>
|
||||
#include <mips/nlm/dev/sec/nlmrsalib.h>
|
||||
|
||||
#ifdef NLM_RSA_DEBUG
|
||||
int print_krp_params(struct cryptkop *krp);
|
||||
static void print_krp_params(struct cryptkop *krp);
|
||||
#endif
|
||||
|
||||
static int xlp_rsa_init(struct xlp_rsa_softc *sc, int node);
|
||||
@ -97,7 +98,7 @@ static device_method_t xlp_rsa_methods[] = {
|
||||
|
||||
/* crypto device methods */
|
||||
DEVMETHOD(cryptodev_newsession, xlp_rsa_newsession),
|
||||
DEVMETHOD(cryptodev_freesession,xlp_rsa_freesession),
|
||||
DEVMETHOD(cryptodev_freesession, xlp_rsa_freesession),
|
||||
DEVMETHOD(cryptodev_kprocess, xlp_rsa_kprocess),
|
||||
|
||||
DEVMETHOD_END
|
||||
@ -113,29 +114,24 @@ static devclass_t xlp_rsa_devclass;
|
||||
DRIVER_MODULE(nlmrsa, pci, xlp_rsa_driver, xlp_rsa_devclass, 0, 0);
|
||||
MODULE_DEPEND(nlmrsa, crypto, 1, 1, 1);
|
||||
|
||||
void
|
||||
nlm_xlprsaecc_msgring_handler(int vc, int size, int code, int src_id,
|
||||
struct nlm_fmn_msg *msg, void *data);
|
||||
|
||||
#ifdef NLM_RSA_DEBUG
|
||||
int
|
||||
static void
|
||||
print_krp_params(struct cryptkop *krp)
|
||||
{
|
||||
int i;
|
||||
|
||||
printf("krp->krp_op :%d\n",krp->krp_op);
|
||||
printf("krp->krp_status :%d\n",krp->krp_status);
|
||||
printf("krp->krp_iparams:%d\n",krp->krp_iparams);
|
||||
printf("krp->krp_oparams:%d\n",krp->krp_oparams);
|
||||
for (i=0;i<krp->krp_iparams+krp->krp_oparams;i++) {
|
||||
printf("krp->krp_param[%d].crp_p :0x%llx\n",i,
|
||||
printf("krp->krp_op :%d\n", krp->krp_op);
|
||||
printf("krp->krp_status :%d\n", krp->krp_status);
|
||||
printf("krp->krp_iparams:%d\n", krp->krp_iparams);
|
||||
printf("krp->krp_oparams:%d\n", krp->krp_oparams);
|
||||
for (i = 0; i < krp->krp_iparams + krp->krp_oparams; i++) {
|
||||
printf("krp->krp_param[%d].crp_p :0x%llx\n", i,
|
||||
(unsigned long long)krp->krp_param[i].crp_p);
|
||||
printf("krp->krp_param[%d].crp_nbits :%d\n",i,
|
||||
printf("krp->krp_param[%d].crp_nbits :%d\n", i,
|
||||
krp->krp_param[i].crp_nbits);
|
||||
printf("krp->krp_param[%d].crp_nbytes :%d\n",i,
|
||||
(krp->krp_param[i].crp_nbits+7)/8);
|
||||
printf("krp->krp_param[%d].crp_nbytes :%d\n", i,
|
||||
howmany(krp->krp_param[i].crp_nbits, 8));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -143,7 +139,7 @@ static int
|
||||
xlp_rsa_init(struct xlp_rsa_softc *sc, int node)
|
||||
{
|
||||
struct xlp_rsa_command *cmd = NULL;
|
||||
uint32_t size, fbvc, dstvc, endsel, regval;
|
||||
uint32_t fbvc, dstvc, endsel, regval;
|
||||
struct nlm_fmn_msg m;
|
||||
int err, ret, i;
|
||||
uint64_t base;
|
||||
@ -155,37 +151,36 @@ xlp_rsa_init(struct xlp_rsa_softc *sc, int node)
|
||||
printf("Couldn't register rsa/ecc msgring handler\n");
|
||||
goto errout;
|
||||
}
|
||||
m.msg[0] = m.msg[1] = m.msg[2] = m.msg[3] = 0;
|
||||
fbvc = nlm_cpuid() / CMS_MAX_VCPU_VC;
|
||||
fbvc = nlm_cpuid() * 4 + XLPGE_FB_VC;
|
||||
/* Do the CMS credit initialization */
|
||||
/* Currently it is configured by default to 50 when kernel comes up */
|
||||
|
||||
if ((cmd = malloc(sizeof(struct xlp_rsa_command), M_DEVBUF,
|
||||
M_NOWAIT | M_ZERO)) == NULL) {
|
||||
err = ENOMEM;
|
||||
printf("Failed to allocate mem for cmd\n");
|
||||
goto errout;
|
||||
}
|
||||
size = sizeof(nlm_rsa_ucode_data);
|
||||
if ((cmd->rsasrc = malloc(size, M_DEVBUF, M_NOWAIT | M_ZERO)) == NULL) {
|
||||
err = ENOMEM;
|
||||
printf("Failed to allocate mem for cmd->rsasrc\n");
|
||||
goto errout;
|
||||
}
|
||||
if (((uintptr_t)cmd->rsasrc & (XLP_L2L3_CACHELINE_SIZE - 1))) {
|
||||
err = EINVAL;
|
||||
printf("cmd->rsasrc is not cacheline aligned\n");
|
||||
goto errout;
|
||||
}
|
||||
memcpy(cmd->rsasrc, (uint8_t *)nlm_rsa_ucode_data, size);
|
||||
m.msg[0] = nlm_crypto_form_rsa_ecc_fmn_entry0(1, 0x70, 0,
|
||||
vtophys(cmd->rsasrc));
|
||||
m.msg[1] = nlm_crypto_form_rsa_ecc_fmn_entry1(0, 1, fbvc,
|
||||
vtophys(cmd->rsasrc));
|
||||
/* Software scratch pad */
|
||||
m.msg[2] = (uintptr_t)cmd;
|
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
for (i = 0; i < nitems(nlm_rsa_ucode_data); i++)
|
||||
nlm_rsa_ucode_data[i] = htobe64(nlm_rsa_ucode_data[i]);
|
||||
#endif
|
||||
for (dstvc = sc->rsaecc_vc_start; dstvc <= sc->rsaecc_vc_end; dstvc++) {
|
||||
cmd = malloc(sizeof(struct xlp_rsa_command), M_DEVBUF,
|
||||
M_NOWAIT | M_ZERO);
|
||||
KASSERT(cmd != NULL, ("%s:cmd is NULL\n", __func__));
|
||||
cmd->rsasrc = contigmalloc(sizeof(nlm_rsa_ucode_data),
|
||||
M_DEVBUF,
|
||||
(M_WAITOK | M_ZERO),
|
||||
0UL /* low address */, -1UL /* high address */,
|
||||
XLP_L2L3_CACHELINE_SIZE /* alignment */,
|
||||
0UL /* boundary */);
|
||||
KASSERT(cmd->rsasrc != NULL,
|
||||
("%s:cmd->rsasrc is NULL\n", __func__));
|
||||
memcpy(cmd->rsasrc, nlm_rsa_ucode_data,
|
||||
sizeof(nlm_rsa_ucode_data));
|
||||
m.msg[0] = nlm_crypto_form_rsa_ecc_fmn_entry0(1, 0x70, 0,
|
||||
vtophys(cmd->rsasrc));
|
||||
m.msg[1] = nlm_crypto_form_rsa_ecc_fmn_entry1(0, 1, fbvc,
|
||||
vtophys(cmd->rsasrc));
|
||||
/* Software scratch pad */
|
||||
m.msg[2] = (uintptr_t)cmd;
|
||||
m.msg[3] = 0;
|
||||
|
||||
ret = nlm_fmn_msgsend(dstvc, 3, FMN_SWCODE_RSA, &m);
|
||||
if (ret != 0) {
|
||||
err = -1;
|
||||
@ -215,38 +210,42 @@ void
|
||||
nlm_xlprsaecc_msgring_handler(int vc, int size, int code, int src_id,
|
||||
struct nlm_fmn_msg *msg, void *data)
|
||||
{
|
||||
struct xlp_rsa_command *cmd = NULL;
|
||||
struct xlp_rsa_softc *sc = NULL;
|
||||
struct xlp_rsa_command *cmd;
|
||||
struct xlp_rsa_softc *sc;
|
||||
struct crparam *outparam;
|
||||
int ostart;
|
||||
|
||||
KASSERT(code == FMN_SWCODE_RSA,
|
||||
("%s: bad code = %d, expected code = %d\n", __FUNCTION__, code,
|
||||
("%s: bad code = %d, expected code = %d\n", __func__, code,
|
||||
FMN_SWCODE_RSA));
|
||||
|
||||
sc = (struct xlp_rsa_softc *)data;
|
||||
sc = data;
|
||||
KASSERT(src_id >= sc->rsaecc_vc_start && src_id <= sc->rsaecc_vc_end,
|
||||
("%s: bad src_id = %d, expect %d - %d\n", __FUNCTION__,
|
||||
("%s: bad src_id = %d, expect %d - %d\n", __func__,
|
||||
src_id, sc->rsaecc_vc_start, sc->rsaecc_vc_end));
|
||||
|
||||
cmd = (struct xlp_rsa_command *)(uintptr_t)msg->msg[1];
|
||||
KASSERT(cmd != NULL, ("%s:cmd not received properly\n",
|
||||
__FUNCTION__));
|
||||
KASSERT(cmd != NULL, ("%s:cmd not received properly\n", __func__));
|
||||
|
||||
KASSERT(RSA_ERROR(msg->msg[0]) == 0,
|
||||
("%s: Message rcv msg0 %llx msg1 %llx err %x \n", __FUNCTION__,
|
||||
(unsigned long long)msg->msg[0], (unsigned long long)msg->msg[1],
|
||||
(int)RSA_ERROR(msg->msg[0])));
|
||||
if (RSA_ERROR(msg->msg[0]) != 0) {
|
||||
printf("%s: Message rcv msg0 %llx msg1 %llx err %x \n",
|
||||
__func__, (unsigned long long)msg->msg[0],
|
||||
(unsigned long long)msg->msg[1],
|
||||
(int)RSA_ERROR(msg->msg[0]));
|
||||
cmd->krp->krp_status = EBADMSG;
|
||||
}
|
||||
|
||||
xlp_rsa_inp2hwformat(((uint8_t *)cmd->rsasrc+
|
||||
(cmd->rsaopsize*cmd->krp->krp_iparams)),
|
||||
cmd->krp->krp_param[cmd->krp->krp_iparams].crp_p,
|
||||
((cmd->krp->krp_param[cmd->krp->krp_iparams].crp_nbits+7)/8), 1);
|
||||
|
||||
if (cmd->krp != NULL)
|
||||
if (cmd->krp != NULL) {
|
||||
ostart = cmd->krp->krp_iparams;
|
||||
outparam = &cmd->krp->krp_param[ostart];
|
||||
xlp_rsa_inp2hwformat(cmd->rsasrc + cmd->rsaopsize * ostart,
|
||||
outparam->crp_p,
|
||||
howmany(outparam->crp_nbits, 8),
|
||||
1);
|
||||
crypto_kdone(cmd->krp);
|
||||
}
|
||||
|
||||
xlp_free_cmd_params(cmd);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -279,7 +278,7 @@ xlp_rsa_attach(device_t dev)
|
||||
freq = nlm_set_device_frequency(node, DFS_DEVICE_RSA, 250);
|
||||
if (bootverbose)
|
||||
device_printf(dev, "RSA Freq: %dMHz\n", freq);
|
||||
if(pci_get_device(dev) == PCI_DEVICE_ID_NLM_RSA) {
|
||||
if (pci_get_device(dev) == PCI_DEVICE_ID_NLM_RSA) {
|
||||
device_set_desc(dev, "XLP RSA/ECC Accelerator");
|
||||
if ((sc->sc_cid = crypto_get_driverid(dev,
|
||||
CRYPTOCAP_F_HARDWARE)) < 0) {
|
||||
@ -287,7 +286,7 @@ xlp_rsa_attach(device_t dev)
|
||||
goto error_exit;
|
||||
}
|
||||
if (crypto_kregister(sc->sc_cid, CRK_MOD_EXP, 0) != 0)
|
||||
printf("register failed for CRK_MOD_EXP\n");
|
||||
goto error_exit;
|
||||
|
||||
base = nlm_get_rsa_pcibase(node);
|
||||
qstart = nlm_qidstart(base);
|
||||
@ -302,7 +301,6 @@ xlp_rsa_attach(device_t dev)
|
||||
|
||||
error_exit:
|
||||
return (ENXIO);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@ -323,8 +321,8 @@ static int
|
||||
xlp_rsa_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
|
||||
{
|
||||
struct xlp_rsa_softc *sc = device_get_softc(dev);
|
||||
int sesn;
|
||||
struct xlp_rsa_session *ses = NULL;
|
||||
int sesn;
|
||||
|
||||
if (sidp == NULL || cri == NULL || sc == NULL)
|
||||
return (EINVAL);
|
||||
@ -346,7 +344,7 @@ xlp_rsa_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
|
||||
|
||||
if (ses == NULL) {
|
||||
sesn = sc->sc_nsessions;
|
||||
ses = malloc((sesn + 1)*sizeof(struct xlp_rsa_session),
|
||||
ses = malloc((sesn + 1) * sizeof(*ses),
|
||||
M_DEVBUF, M_NOWAIT);
|
||||
if (ses == NULL)
|
||||
return (ENOMEM);
|
||||
@ -392,43 +390,44 @@ xlp_rsa_freesession(device_t dev, u_int64_t tid)
|
||||
static void
|
||||
xlp_free_cmd_params(struct xlp_rsa_command *cmd)
|
||||
{
|
||||
if (cmd->rsasrc != NULL)
|
||||
free(cmd->rsasrc, M_DEVBUF);
|
||||
if (cmd != NULL)
|
||||
free(cmd, M_DEVBUF);
|
||||
return;
|
||||
|
||||
if (cmd == NULL)
|
||||
return;
|
||||
if (cmd->rsasrc != NULL) {
|
||||
if (cmd->krp == NULL) /* Micro code load */
|
||||
contigfree(cmd->rsasrc, sizeof(nlm_rsa_ucode_data),
|
||||
M_DEVBUF);
|
||||
else
|
||||
free(cmd->rsasrc, M_DEVBUF);
|
||||
}
|
||||
free(cmd, M_DEVBUF);
|
||||
}
|
||||
|
||||
static int
|
||||
xlp_get_rsa_opsize(struct xlp_rsa_command *cmd, unsigned int bits)
|
||||
{
|
||||
if (bits == 0)
|
||||
|
||||
if (bits == 0 || bits > 8192)
|
||||
return (-1);
|
||||
/* XLP hardware expects always a fixed size with unused bytes
|
||||
* zeroed out in the input data */
|
||||
if (bits <= 512) {
|
||||
cmd->rsatype = 0x40;
|
||||
cmd->rsaopsize = (512/8);
|
||||
return (0);
|
||||
} else if ((bits > 512) && (bits <= 1024)) {
|
||||
cmd->rsaopsize = 64;
|
||||
} else if (bits <= 1024) {
|
||||
cmd->rsatype = 0x41;
|
||||
cmd->rsaopsize = (1024/8);
|
||||
return (0);
|
||||
} else if ((bits > 1024) && (bits <= 2048)) {
|
||||
cmd->rsaopsize = 128;
|
||||
} else if (bits <= 2048) {
|
||||
cmd->rsatype = 0x42;
|
||||
cmd->rsaopsize = (2048/8);
|
||||
return (0);
|
||||
} else if ((bits > 2048) && (bits <= 4096)) {
|
||||
cmd->rsaopsize = 256;
|
||||
} else if (bits <= 4096) {
|
||||
cmd->rsatype = 0x43;
|
||||
cmd->rsaopsize = (4096/8);
|
||||
return (0);
|
||||
} else if ((bits > 4096) && (bits <= 8192)) {
|
||||
cmd->rsaopsize = 512;
|
||||
} else if (bits <= 8192) {
|
||||
cmd->rsatype = 0x44;
|
||||
cmd->rsaopsize = (8192/8);
|
||||
return (0);
|
||||
} else {
|
||||
return (-1);
|
||||
cmd->rsaopsize = 1024;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -436,25 +435,25 @@ xlp_rsa_inp2hwformat(uint8_t *src, uint8_t *dst, uint32_t paramsize,
|
||||
uint8_t result)
|
||||
{
|
||||
uint32_t pdwords, pbytes;
|
||||
int i=0, j=0, k=0;
|
||||
int i, j, k;
|
||||
|
||||
pdwords = (paramsize / 8);
|
||||
pbytes = (paramsize % 8);
|
||||
pdwords = paramsize / 8;
|
||||
pbytes = paramsize % 8;
|
||||
|
||||
for (i = 0, k = 0; i < pdwords; i++) {
|
||||
/* copy dwords of inp/hw to hw/out format */
|
||||
for (j = 7; j >= 0; j--, k++)
|
||||
dst[(i*8)+j] = src[k];
|
||||
dst[i * 8 + j] = src[k];
|
||||
}
|
||||
if (pbytes) {
|
||||
if (!result) {
|
||||
if (result == 0) {
|
||||
/* copy rem bytes of input data to hw format */
|
||||
for (j = 7; k < paramsize; j--, k++)
|
||||
dst[(i*8)+j] = src[k];
|
||||
dst[i * 8 + j] = src[k];
|
||||
} else {
|
||||
/* copy rem bytes of hw data to exp output format */
|
||||
for (j = 7; k < paramsize; j--, k++)
|
||||
dst[k] = src[(i*8)+j];
|
||||
dst[k] = src[i * 8 + j];
|
||||
}
|
||||
}
|
||||
|
||||
@ -469,15 +468,15 @@ nlm_crypto_complete_rsa_request(struct xlp_rsa_softc *sc,
|
||||
struct nlm_fmn_msg m;
|
||||
int ret;
|
||||
|
||||
fbvc = nlm_cpuid() / CMS_MAX_VCPU_VC;
|
||||
m.msg[0] = m.msg[1] = m.msg[2] = m.msg[3] = 0;
|
||||
fbvc = nlm_cpuid() * 4 + XLPGE_FB_VC;
|
||||
|
||||
m.msg[0] = nlm_crypto_form_rsa_ecc_fmn_entry0(1, cmd->rsatype,
|
||||
cmd->rsafn, vtophys(cmd->rsasrc));
|
||||
m.msg[1] = nlm_crypto_form_rsa_ecc_fmn_entry1(0, 1, fbvc,
|
||||
vtophys(cmd->rsasrc + (cmd->rsaopsize * cmd->krp->krp_iparams)));
|
||||
vtophys(cmd->rsasrc + cmd->rsaopsize * cmd->krp->krp_iparams));
|
||||
/* Software scratch pad */
|
||||
m.msg[2] = (uintptr_t)cmd;
|
||||
m.msg[3] = 0;
|
||||
|
||||
/* Send the message to rsa engine vc */
|
||||
ret = nlm_fmn_msgsend(sc->rsaecc_vc_start, 3, FMN_SWCODE_RSA, &m);
|
||||
@ -494,57 +493,57 @@ static int
|
||||
xlp_rsa_kprocess(device_t dev, struct cryptkop *krp, int hint)
|
||||
{
|
||||
struct xlp_rsa_softc *sc = device_get_softc(dev);
|
||||
struct xlp_rsa_command *cmd = NULL;
|
||||
int err = -1, i;
|
||||
struct xlp_rsa_command *cmd;
|
||||
struct crparam *kp;
|
||||
int err, i;
|
||||
|
||||
if (krp == NULL || krp->krp_callback == NULL)
|
||||
return (EINVAL);
|
||||
|
||||
if ((cmd = malloc(sizeof(struct xlp_rsa_command), M_DEVBUF,
|
||||
M_NOWAIT | M_ZERO)) == NULL) {
|
||||
err = ENOMEM;
|
||||
goto errout;
|
||||
}
|
||||
cmd = malloc(sizeof(struct xlp_rsa_command), M_DEVBUF,
|
||||
M_NOWAIT | M_ZERO);
|
||||
KASSERT(cmd != NULL, ("%s:cmd is NULL\n", __func__));
|
||||
cmd->krp = krp;
|
||||
|
||||
#ifdef NLM_RSA_DEBUG
|
||||
print_krp_params(krp);
|
||||
#endif
|
||||
err = EOPNOTSUPP;
|
||||
switch (krp->krp_op) {
|
||||
case CRK_MOD_EXP:
|
||||
if (krp->krp_iparams == 3 && krp->krp_oparams == 1)
|
||||
break;
|
||||
goto errout;
|
||||
default:
|
||||
printf("Op:%d not yet supported\n", krp->krp_op);
|
||||
device_printf(dev, "Op:%d not yet supported\n", krp->krp_op);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
if ((xlp_get_rsa_opsize(cmd,
|
||||
krp->krp_param[krp->krp_iparams-1].crp_nbits)) != 0) {
|
||||
err = xlp_get_rsa_opsize(cmd,
|
||||
krp->krp_param[krp->krp_iparams - 1].crp_nbits);
|
||||
if (err != 0) {
|
||||
err = EINVAL;
|
||||
goto errout;
|
||||
}
|
||||
cmd->rsafn = 0; /* Mod Exp */
|
||||
if ((cmd->rsasrc = malloc((cmd->rsaopsize *
|
||||
(krp->krp_iparams+krp->krp_oparams)), M_DEVBUF,
|
||||
M_NOWAIT | M_ZERO)) == NULL) {
|
||||
cmd->rsasrc = malloc(
|
||||
cmd->rsaopsize * (krp->krp_iparams + krp->krp_oparams),
|
||||
M_DEVBUF,
|
||||
M_NOWAIT | M_ZERO);
|
||||
if (cmd->rsasrc == NULL) {
|
||||
err = ENOMEM;
|
||||
goto errout;
|
||||
}
|
||||
if (((uintptr_t)cmd->rsasrc & (XLP_L2L3_CACHELINE_SIZE - 1))) {
|
||||
err = EINVAL;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
for (i=0;i<krp->krp_iparams;i++) {
|
||||
KASSERT(krp->krp_param[i].crp_nbits != 0,
|
||||
("%s: parameter[%d]'s length is zero\n", __FUNCTION__, i));
|
||||
xlp_rsa_inp2hwformat(krp->krp_param[i].crp_p,
|
||||
((uint8_t *)cmd->rsasrc+(i*cmd->rsaopsize)),
|
||||
((krp->krp_param[i].crp_nbits+7)/8), 0);
|
||||
for (i = 0, kp = krp->krp_param; i < krp->krp_iparams; i++, kp++) {
|
||||
KASSERT(kp->crp_nbits != 0,
|
||||
("%s: parameter[%d]'s length is zero\n", __func__, i));
|
||||
xlp_rsa_inp2hwformat(kp->crp_p,
|
||||
cmd->rsasrc + i * cmd->rsaopsize,
|
||||
howmany(kp->crp_nbits, 8), 0);
|
||||
}
|
||||
if (nlm_crypto_complete_rsa_request(sc, cmd) != 0)
|
||||
err = nlm_crypto_complete_rsa_request(sc, cmd);
|
||||
if (err != 0)
|
||||
goto errout;
|
||||
|
||||
return (0);
|
||||
|
@ -30,12 +30,10 @@
|
||||
#ifndef _NLMRSALIB_H_
|
||||
#define _NLMRSALIB_H_
|
||||
|
||||
#define XLP_RSA_SESSION(sid) ((sid) & 0x000007ff)
|
||||
#define XLP_RSA_SID(crd,ses) (((crd) << 28) | ((ses) & 0x7ff))
|
||||
#define XLP_RSA_SESSION(sid) ((sid) & 0x000007ff)
|
||||
#define XLP_RSA_SID(crd,ses) (((crd) << 28) | ((ses) & 0x7ff))
|
||||
|
||||
#define NUM_RSAECC_VC 9
|
||||
|
||||
#define RSA_ERROR(__msg0) ((__msg0 >> 53) & 0x1f)
|
||||
#define RSA_ERROR(msg0) (((msg0) >> 53) & 0x1f)
|
||||
|
||||
struct xlp_rsa_session {
|
||||
uint32_t sessionid;
|
||||
@ -65,4 +63,8 @@ struct xlp_rsa_softc {
|
||||
int rsaecc_vc_end;
|
||||
};
|
||||
|
||||
void
|
||||
nlm_xlprsaecc_msgring_handler(int vc, int size, int code, int src_id,
|
||||
struct nlm_fmn_msg *msg, void *data);
|
||||
|
||||
#endif /* _NLMRSALIB_H_ */
|
||||
|
@ -11,7 +11,7 @@ SRCS+= agent.h core_priv.h mad.c notice.c smi.h umem.c uverbs_marshall.c
|
||||
SRCS+= cache.c device.c mad_priv.h packer.c sysfs.c user_mad.c verbs.c
|
||||
SRCS+= cm.c fmr_pool.c mad_rmpp.c sa.h ucm.c uverbs.h cma.c
|
||||
SRCS+= linux_compat.c linux_radix.c linux_idr.c
|
||||
SRCS+= vnode_if.h device_if.h bus_if.h pci_if.h opt_inet.h
|
||||
SRCS+= vnode_if.h device_if.h bus_if.h pci_if.h opt_inet.h opt_inet6.h
|
||||
|
||||
CFLAGS+= -I${.CURDIR}/../../ofed/drivers/infiniband/core
|
||||
CFLAGS+= -I${.CURDIR}/../mlx4ib
|
||||
|
@ -366,13 +366,9 @@ SUBDIR+= users
|
||||
SUBDIR+= who
|
||||
.endif
|
||||
|
||||
.if ${MACHINE_ARCH} == "amd64" || ${MACHINE_ARCH} == "ia64" || \
|
||||
${MACHINE_ARCH} == "sparc64" || ${MACHINE_ARCH} == "i386" || \
|
||||
(${MACHINE_ARCH} == "armv6" && ${COMPILER_TYPE} == "clang")
|
||||
.if ${MK_SVN} == "yes" || ${MK_SVNLITE} == "yes"
|
||||
SUBDIR+= svn
|
||||
.endif
|
||||
.endif
|
||||
|
||||
.include <bsd.arch.inc.mk>
|
||||
|
||||
|
@ -180,7 +180,7 @@ a continuation of the previous line.
|
||||
The
|
||||
.Nm
|
||||
file is preprocessed by a limited subset of
|
||||
.Xr cpp 1
|
||||
.Xr cpp 1
|
||||
internally, allowing the inclusion of shared files such as
|
||||
lists of company holidays or meetings.
|
||||
This limited subset consists of \fB#include #ifndef #endif\fR and \fB#define\fR.
|
||||
|
@ -97,7 +97,9 @@
|
||||
#define HAVE_ARPA_INET_H 1
|
||||
|
||||
/* Define if compiler provides atomic builtins */
|
||||
#if !defined(__mips__) && !defined(__arm__)
|
||||
#define HAVE_ATOMIC_BUILTINS 1
|
||||
#endif
|
||||
|
||||
/* Define if BONE_VERSION is defined in sys/socket.h */
|
||||
/* #undef HAVE_BONE_VERSION */
|
||||
|
@ -153,7 +153,7 @@
|
||||
#define SVN_FS_WANT_DB_PATCH 14
|
||||
|
||||
/* Define if compiler provides atomic builtins */
|
||||
#define SVN_HAS_ATOMIC_BUILTINS 1
|
||||
#define SVN_HAS_ATOMIC_BUILTINS 0
|
||||
|
||||
/* Is GNOME Keyring support enabled? */
|
||||
/* #undef SVN_HAVE_GNOME_KEYRING */
|
||||
|
@ -6,8 +6,8 @@ PROG= bhyve
|
||||
|
||||
DEBUG_FLAGS= -g -O0
|
||||
|
||||
SRCS= acpi.c atpic.c bhyverun.c consport.c dbgport.c elcr.c inout.c
|
||||
SRCS+= ioapic.c mem.c mevent.c mptbl.c
|
||||
SRCS= acpi.c atpic.c bhyverun.c block_if.c consport.c dbgport.c elcr.c
|
||||
SRCS+= inout.c ioapic.c mem.c mevent.c mptbl.c pci_ahci.c
|
||||
SRCS+= pci_emul.c pci_hostbridge.c pci_passthru.c pci_virtio_block.c
|
||||
SRCS+= pci_virtio_net.c pci_uart.c pit_8254.c pmtmr.c post.c rtc.c
|
||||
SRCS+= virtio.c xmsr.c spinup_ap.c
|
||||
|
304
usr.sbin/bhyve/ahci.h
Normal file
304
usr.sbin/bhyve/ahci.h
Normal file
@ -0,0 +1,304 @@
|
||||
/*-
|
||||
* Copyright (c) 1998 - 2008 Søren Schmidt <sos@FreeBSD.org>
|
||||
* Copyright (c) 2009-2012 Alexander Motin <mav@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* without modification, immediately at the beginning of the file.
|
||||
* 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 ``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 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 _AHCI_H_
|
||||
#define _AHCI_H_
|
||||
|
||||
/* ATA register defines */
|
||||
#define ATA_DATA 0 /* (RW) data */
|
||||
|
||||
#define ATA_FEATURE 1 /* (W) feature */
|
||||
#define ATA_F_DMA 0x01 /* enable DMA */
|
||||
#define ATA_F_OVL 0x02 /* enable overlap */
|
||||
|
||||
#define ATA_COUNT 2 /* (W) sector count */
|
||||
|
||||
#define ATA_SECTOR 3 /* (RW) sector # */
|
||||
#define ATA_CYL_LSB 4 /* (RW) cylinder# LSB */
|
||||
#define ATA_CYL_MSB 5 /* (RW) cylinder# MSB */
|
||||
#define ATA_DRIVE 6 /* (W) Sector/Drive/Head */
|
||||
#define ATA_D_LBA 0x40 /* use LBA addressing */
|
||||
#define ATA_D_IBM 0xa0 /* 512 byte sectors, ECC */
|
||||
|
||||
#define ATA_COMMAND 7 /* (W) command */
|
||||
|
||||
#define ATA_ERROR 8 /* (R) error */
|
||||
#define ATA_E_ILI 0x01 /* illegal length */
|
||||
#define ATA_E_NM 0x02 /* no media */
|
||||
#define ATA_E_ABORT 0x04 /* command aborted */
|
||||
#define ATA_E_MCR 0x08 /* media change request */
|
||||
#define ATA_E_IDNF 0x10 /* ID not found */
|
||||
#define ATA_E_MC 0x20 /* media changed */
|
||||
#define ATA_E_UNC 0x40 /* uncorrectable data */
|
||||
#define ATA_E_ICRC 0x80 /* UDMA crc error */
|
||||
#define ATA_E_ATAPI_SENSE_MASK 0xf0 /* ATAPI sense key mask */
|
||||
|
||||
#define ATA_IREASON 9 /* (R) interrupt reason */
|
||||
#define ATA_I_CMD 0x01 /* cmd (1) | data (0) */
|
||||
#define ATA_I_IN 0x02 /* read (1) | write (0) */
|
||||
#define ATA_I_RELEASE 0x04 /* released bus (1) */
|
||||
#define ATA_I_TAGMASK 0xf8 /* tag mask */
|
||||
|
||||
#define ATA_STATUS 10 /* (R) status */
|
||||
#define ATA_ALTSTAT 11 /* (R) alternate status */
|
||||
#define ATA_S_ERROR 0x01 /* error */
|
||||
#define ATA_S_INDEX 0x02 /* index */
|
||||
#define ATA_S_CORR 0x04 /* data corrected */
|
||||
#define ATA_S_DRQ 0x08 /* data request */
|
||||
#define ATA_S_DSC 0x10 /* drive seek completed */
|
||||
#define ATA_S_SERVICE 0x10 /* drive needs service */
|
||||
#define ATA_S_DWF 0x20 /* drive write fault */
|
||||
#define ATA_S_DMA 0x20 /* DMA ready */
|
||||
#define ATA_S_READY 0x40 /* drive ready */
|
||||
#define ATA_S_BUSY 0x80 /* busy */
|
||||
|
||||
#define ATA_CONTROL 12 /* (W) control */
|
||||
#define ATA_A_IDS 0x02 /* disable interrupts */
|
||||
#define ATA_A_RESET 0x04 /* RESET controller */
|
||||
#define ATA_A_4BIT 0x08 /* 4 head bits */
|
||||
#define ATA_A_HOB 0x80 /* High Order Byte enable */
|
||||
|
||||
/* SATA register defines */
|
||||
#define ATA_SSTATUS 13
|
||||
#define ATA_SS_DET_MASK 0x0000000f
|
||||
#define ATA_SS_DET_NO_DEVICE 0x00000000
|
||||
#define ATA_SS_DET_DEV_PRESENT 0x00000001
|
||||
#define ATA_SS_DET_PHY_ONLINE 0x00000003
|
||||
#define ATA_SS_DET_PHY_OFFLINE 0x00000004
|
||||
|
||||
#define ATA_SS_SPD_MASK 0x000000f0
|
||||
#define ATA_SS_SPD_NO_SPEED 0x00000000
|
||||
#define ATA_SS_SPD_GEN1 0x00000010
|
||||
#define ATA_SS_SPD_GEN2 0x00000020
|
||||
#define ATA_SS_SPD_GEN3 0x00000040
|
||||
|
||||
#define ATA_SS_IPM_MASK 0x00000f00
|
||||
#define ATA_SS_IPM_NO_DEVICE 0x00000000
|
||||
#define ATA_SS_IPM_ACTIVE 0x00000100
|
||||
#define ATA_SS_IPM_PARTIAL 0x00000200
|
||||
#define ATA_SS_IPM_SLUMBER 0x00000600
|
||||
|
||||
#define ATA_SERROR 14
|
||||
#define ATA_SE_DATA_CORRECTED 0x00000001
|
||||
#define ATA_SE_COMM_CORRECTED 0x00000002
|
||||
#define ATA_SE_DATA_ERR 0x00000100
|
||||
#define ATA_SE_COMM_ERR 0x00000200
|
||||
#define ATA_SE_PROT_ERR 0x00000400
|
||||
#define ATA_SE_HOST_ERR 0x00000800
|
||||
#define ATA_SE_PHY_CHANGED 0x00010000
|
||||
#define ATA_SE_PHY_IERROR 0x00020000
|
||||
#define ATA_SE_COMM_WAKE 0x00040000
|
||||
#define ATA_SE_DECODE_ERR 0x00080000
|
||||
#define ATA_SE_PARITY_ERR 0x00100000
|
||||
#define ATA_SE_CRC_ERR 0x00200000
|
||||
#define ATA_SE_HANDSHAKE_ERR 0x00400000
|
||||
#define ATA_SE_LINKSEQ_ERR 0x00800000
|
||||
#define ATA_SE_TRANSPORT_ERR 0x01000000
|
||||
#define ATA_SE_UNKNOWN_FIS 0x02000000
|
||||
#define ATA_SE_EXCHANGED 0x04000000
|
||||
|
||||
#define ATA_SCONTROL 15
|
||||
#define ATA_SC_DET_MASK 0x0000000f
|
||||
#define ATA_SC_DET_IDLE 0x00000000
|
||||
#define ATA_SC_DET_RESET 0x00000001
|
||||
#define ATA_SC_DET_DISABLE 0x00000004
|
||||
|
||||
#define ATA_SC_SPD_MASK 0x000000f0
|
||||
#define ATA_SC_SPD_NO_SPEED 0x00000000
|
||||
#define ATA_SC_SPD_SPEED_GEN1 0x00000010
|
||||
#define ATA_SC_SPD_SPEED_GEN2 0x00000020
|
||||
#define ATA_SC_SPD_SPEED_GEN3 0x00000040
|
||||
|
||||
#define ATA_SC_IPM_MASK 0x00000f00
|
||||
#define ATA_SC_IPM_NONE 0x00000000
|
||||
#define ATA_SC_IPM_DIS_PARTIAL 0x00000100
|
||||
#define ATA_SC_IPM_DIS_SLUMBER 0x00000200
|
||||
|
||||
#define ATA_SACTIVE 16
|
||||
|
||||
#define AHCI_MAX_PORTS 32
|
||||
#define AHCI_MAX_SLOTS 32
|
||||
|
||||
/* SATA AHCI v1.0 register defines */
|
||||
#define AHCI_CAP 0x00
|
||||
#define AHCI_CAP_NPMASK 0x0000001f
|
||||
#define AHCI_CAP_SXS 0x00000020
|
||||
#define AHCI_CAP_EMS 0x00000040
|
||||
#define AHCI_CAP_CCCS 0x00000080
|
||||
#define AHCI_CAP_NCS 0x00001F00
|
||||
#define AHCI_CAP_NCS_SHIFT 8
|
||||
#define AHCI_CAP_PSC 0x00002000
|
||||
#define AHCI_CAP_SSC 0x00004000
|
||||
#define AHCI_CAP_PMD 0x00008000
|
||||
#define AHCI_CAP_FBSS 0x00010000
|
||||
#define AHCI_CAP_SPM 0x00020000
|
||||
#define AHCI_CAP_SAM 0x00080000
|
||||
#define AHCI_CAP_ISS 0x00F00000
|
||||
#define AHCI_CAP_ISS_SHIFT 20
|
||||
#define AHCI_CAP_SCLO 0x01000000
|
||||
#define AHCI_CAP_SAL 0x02000000
|
||||
#define AHCI_CAP_SALP 0x04000000
|
||||
#define AHCI_CAP_SSS 0x08000000
|
||||
#define AHCI_CAP_SMPS 0x10000000
|
||||
#define AHCI_CAP_SSNTF 0x20000000
|
||||
#define AHCI_CAP_SNCQ 0x40000000
|
||||
#define AHCI_CAP_64BIT 0x80000000
|
||||
|
||||
#define AHCI_GHC 0x04
|
||||
#define AHCI_GHC_AE 0x80000000
|
||||
#define AHCI_GHC_MRSM 0x00000004
|
||||
#define AHCI_GHC_IE 0x00000002
|
||||
#define AHCI_GHC_HR 0x00000001
|
||||
|
||||
#define AHCI_IS 0x08
|
||||
#define AHCI_PI 0x0c
|
||||
#define AHCI_VS 0x10
|
||||
|
||||
#define AHCI_CCCC 0x14
|
||||
#define AHCI_CCCC_TV_MASK 0xffff0000
|
||||
#define AHCI_CCCC_TV_SHIFT 16
|
||||
#define AHCI_CCCC_CC_MASK 0x0000ff00
|
||||
#define AHCI_CCCC_CC_SHIFT 8
|
||||
#define AHCI_CCCC_INT_MASK 0x000000f8
|
||||
#define AHCI_CCCC_INT_SHIFT 3
|
||||
#define AHCI_CCCC_EN 0x00000001
|
||||
#define AHCI_CCCP 0x18
|
||||
|
||||
#define AHCI_EM_LOC 0x1C
|
||||
#define AHCI_EM_CTL 0x20
|
||||
#define AHCI_EM_MR 0x00000001
|
||||
#define AHCI_EM_TM 0x00000100
|
||||
#define AHCI_EM_RST 0x00000200
|
||||
#define AHCI_EM_LED 0x00010000
|
||||
#define AHCI_EM_SAFTE 0x00020000
|
||||
#define AHCI_EM_SES2 0x00040000
|
||||
#define AHCI_EM_SGPIO 0x00080000
|
||||
#define AHCI_EM_SMB 0x01000000
|
||||
#define AHCI_EM_XMT 0x02000000
|
||||
#define AHCI_EM_ALHD 0x04000000
|
||||
#define AHCI_EM_PM 0x08000000
|
||||
|
||||
#define AHCI_CAP2 0x24
|
||||
#define AHCI_CAP2_BOH 0x00000001
|
||||
#define AHCI_CAP2_NVMP 0x00000002
|
||||
#define AHCI_CAP2_APST 0x00000004
|
||||
|
||||
#define AHCI_OFFSET 0x100
|
||||
#define AHCI_STEP 0x80
|
||||
|
||||
#define AHCI_P_CLB 0x00
|
||||
#define AHCI_P_CLBU 0x04
|
||||
#define AHCI_P_FB 0x08
|
||||
#define AHCI_P_FBU 0x0c
|
||||
#define AHCI_P_IS 0x10
|
||||
#define AHCI_P_IE 0x14
|
||||
#define AHCI_P_IX_DHR 0x00000001
|
||||
#define AHCI_P_IX_PS 0x00000002
|
||||
#define AHCI_P_IX_DS 0x00000004
|
||||
#define AHCI_P_IX_SDB 0x00000008
|
||||
#define AHCI_P_IX_UF 0x00000010
|
||||
#define AHCI_P_IX_DP 0x00000020
|
||||
#define AHCI_P_IX_PC 0x00000040
|
||||
#define AHCI_P_IX_MP 0x00000080
|
||||
|
||||
#define AHCI_P_IX_PRC 0x00400000
|
||||
#define AHCI_P_IX_IPM 0x00800000
|
||||
#define AHCI_P_IX_OF 0x01000000
|
||||
#define AHCI_P_IX_INF 0x04000000
|
||||
#define AHCI_P_IX_IF 0x08000000
|
||||
#define AHCI_P_IX_HBD 0x10000000
|
||||
#define AHCI_P_IX_HBF 0x20000000
|
||||
#define AHCI_P_IX_TFE 0x40000000
|
||||
#define AHCI_P_IX_CPD 0x80000000
|
||||
|
||||
#define AHCI_P_CMD 0x18
|
||||
#define AHCI_P_CMD_ST 0x00000001
|
||||
#define AHCI_P_CMD_SUD 0x00000002
|
||||
#define AHCI_P_CMD_POD 0x00000004
|
||||
#define AHCI_P_CMD_CLO 0x00000008
|
||||
#define AHCI_P_CMD_FRE 0x00000010
|
||||
#define AHCI_P_CMD_CCS_MASK 0x00001f00
|
||||
#define AHCI_P_CMD_CCS_SHIFT 8
|
||||
#define AHCI_P_CMD_ISS 0x00002000
|
||||
#define AHCI_P_CMD_FR 0x00004000
|
||||
#define AHCI_P_CMD_CR 0x00008000
|
||||
#define AHCI_P_CMD_CPS 0x00010000
|
||||
#define AHCI_P_CMD_PMA 0x00020000
|
||||
#define AHCI_P_CMD_HPCP 0x00040000
|
||||
#define AHCI_P_CMD_MPSP 0x00080000
|
||||
#define AHCI_P_CMD_CPD 0x00100000
|
||||
#define AHCI_P_CMD_ESP 0x00200000
|
||||
#define AHCI_P_CMD_FBSCP 0x00400000
|
||||
#define AHCI_P_CMD_APSTE 0x00800000
|
||||
#define AHCI_P_CMD_ATAPI 0x01000000
|
||||
#define AHCI_P_CMD_DLAE 0x02000000
|
||||
#define AHCI_P_CMD_ALPE 0x04000000
|
||||
#define AHCI_P_CMD_ASP 0x08000000
|
||||
#define AHCI_P_CMD_ICC_MASK 0xf0000000
|
||||
#define AHCI_P_CMD_NOOP 0x00000000
|
||||
#define AHCI_P_CMD_ACTIVE 0x10000000
|
||||
#define AHCI_P_CMD_PARTIAL 0x20000000
|
||||
#define AHCI_P_CMD_SLUMBER 0x60000000
|
||||
|
||||
#define AHCI_P_TFD 0x20
|
||||
#define AHCI_P_SIG 0x24
|
||||
#define AHCI_P_SSTS 0x28
|
||||
#define AHCI_P_SCTL 0x2c
|
||||
#define AHCI_P_SERR 0x30
|
||||
#define AHCI_P_SACT 0x34
|
||||
#define AHCI_P_CI 0x38
|
||||
#define AHCI_P_SNTF 0x3C
|
||||
#define AHCI_P_FBS 0x40
|
||||
#define AHCI_P_FBS_EN 0x00000001
|
||||
#define AHCI_P_FBS_DEC 0x00000002
|
||||
#define AHCI_P_FBS_SDE 0x00000004
|
||||
#define AHCI_P_FBS_DEV 0x00000f00
|
||||
#define AHCI_P_FBS_DEV_SHIFT 8
|
||||
#define AHCI_P_FBS_ADO 0x0000f000
|
||||
#define AHCI_P_FBS_ADO_SHIFT 12
|
||||
#define AHCI_P_FBS_DWE 0x000f0000
|
||||
#define AHCI_P_FBS_DWE_SHIFT 16
|
||||
|
||||
/* Just to be sure, if building as module. */
|
||||
#if MAXPHYS < 512 * 1024
|
||||
#undef MAXPHYS
|
||||
#define MAXPHYS 512 * 1024
|
||||
#endif
|
||||
/* Pessimistic prognosis on number of required S/G entries */
|
||||
#define AHCI_SG_ENTRIES (roundup(btoc(MAXPHYS) + 1, 8))
|
||||
/* Command list. 32 commands. First, 1Kbyte aligned. */
|
||||
#define AHCI_CL_OFFSET 0
|
||||
#define AHCI_CL_SIZE 32
|
||||
/* Command tables. Up to 32 commands, Each, 128byte aligned. */
|
||||
#define AHCI_CT_OFFSET (AHCI_CL_OFFSET + AHCI_CL_SIZE * AHCI_MAX_SLOTS)
|
||||
#define AHCI_CT_SIZE (128 + AHCI_SG_ENTRIES * 16)
|
||||
/* Total main work area. */
|
||||
#define AHCI_WORK_SIZE (AHCI_CT_OFFSET + AHCI_CT_SIZE * ch->numslots)
|
||||
|
||||
#endif /* _AHCI_H_ */
|
@ -41,7 +41,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <pthread.h>
|
||||
#include <pthread_np.h>
|
||||
|
||||
@ -61,9 +60,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include "spinup_ap.h"
|
||||
#include "rtc.h"
|
||||
|
||||
#define DEFAULT_GUEST_HZ 100
|
||||
#define DEFAULT_GUEST_TSLICE 200
|
||||
|
||||
#define GUEST_NIO_PORT 0x488 /* guest upcalls via i/o port */
|
||||
|
||||
#define VMEXIT_SWITCH 0 /* force vcpu switch in mux mode */
|
||||
@ -77,14 +73,11 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
typedef int (*vmexit_handler_t)(struct vmctx *, struct vm_exit *, int *vcpu);
|
||||
|
||||
int guest_tslice = DEFAULT_GUEST_TSLICE;
|
||||
int guest_hz = DEFAULT_GUEST_HZ;
|
||||
char *vmname;
|
||||
|
||||
int guest_ncpus;
|
||||
|
||||
static int pincpu = -1;
|
||||
static int guest_vcpu_mux;
|
||||
static int guest_vmexit_on_hlt, guest_vmexit_on_pause, disable_x2apic;
|
||||
|
||||
static int foundcpus;
|
||||
@ -102,7 +95,7 @@ static void vm_loop(struct vmctx *ctx, int vcpu, uint64_t rip);
|
||||
|
||||
struct vm_exit vmexit[VM_MAXCPU];
|
||||
|
||||
struct fbsdstats {
|
||||
struct bhyvestats {
|
||||
uint64_t vmexit_bogus;
|
||||
uint64_t vmexit_bogus_switch;
|
||||
uint64_t vmexit_hlt;
|
||||
@ -125,28 +118,24 @@ usage(int code)
|
||||
{
|
||||
|
||||
fprintf(stderr,
|
||||
"Usage: %s [-aehABHIP][-g <gdb port>][-z <hz>][-s <pci>]"
|
||||
"[-S <pci>][-p pincpu][-n <pci>][-m lowmem][-M highmem]"
|
||||
"Usage: %s [-aehAHIP][-g <gdb port>][-s <pci>][-S <pci>]"
|
||||
"[-c vcpus][-p pincpu][-m mem]"
|
||||
" <vmname>\n"
|
||||
" -a: local apic is in XAPIC mode (default is X2APIC)\n"
|
||||
" -A: create an ACPI table\n"
|
||||
" -g: gdb port (default is %d and 0 means don't open)\n"
|
||||
" -c: # cpus (default 1)\n"
|
||||
" -p: pin vcpu 'n' to host cpu 'pincpu + n'\n"
|
||||
" -B: inject breakpoint exception on vm entry\n"
|
||||
" -H: vmexit from the guest on hlt\n"
|
||||
" -I: present an ioapic to the guest\n"
|
||||
" -P: vmexit from the guest on pause\n"
|
||||
" -e: exit on unhandled i/o access\n"
|
||||
" -h: help\n"
|
||||
" -z: guest hz (default is %d)\n"
|
||||
" -s: <slot,driver,configinfo> PCI slot config\n"
|
||||
" -S: <slot,driver,configinfo> legacy PCI slot config\n"
|
||||
" -m: memory size in MB\n"
|
||||
" -x: mux vcpus to 1 hcpu\n"
|
||||
" -t: mux vcpu timeslice hz (default %d)\n",
|
||||
progname, DEFAULT_GDB_PORT, DEFAULT_GUEST_HZ,
|
||||
DEFAULT_GUEST_TSLICE);
|
||||
" -m: memory size in MB\n",
|
||||
progname, DEFAULT_GDB_PORT);
|
||||
|
||||
exit(code);
|
||||
}
|
||||
|
||||
@ -178,13 +167,6 @@ fbsdrun_vmexit_on_hlt(void)
|
||||
return (guest_vmexit_on_hlt);
|
||||
}
|
||||
|
||||
int
|
||||
fbsdrun_muxed(void)
|
||||
{
|
||||
|
||||
return (guest_vcpu_mux);
|
||||
}
|
||||
|
||||
static void *
|
||||
fbsdrun_start_thread(void *param)
|
||||
{
|
||||
@ -226,7 +208,7 @@ fbsdrun_addcpu(struct vmctx *ctx, int vcpu, uint64_t rip)
|
||||
vmexit[vcpu].rip = rip;
|
||||
vmexit[vcpu].inst_length = 0;
|
||||
|
||||
if (vcpu == BSP || !guest_vcpu_mux){
|
||||
if (vcpu == BSP) {
|
||||
mt_vmm_info[vcpu].mt_ctx = ctx;
|
||||
mt_vmm_info[vcpu].mt_vcpu = vcpu;
|
||||
|
||||
@ -264,17 +246,10 @@ static int
|
||||
vmexit_handle_notify(struct vmctx *ctx, struct vm_exit *vme, int *pvcpu,
|
||||
uint32_t eax)
|
||||
{
|
||||
#if PG_DEBUG /* put all types of debug here */
|
||||
if (eax == 0) {
|
||||
pause_noswitch = 1;
|
||||
} else if (eax == 1) {
|
||||
pause_noswitch = 0;
|
||||
} else {
|
||||
pause_noswitch = 0;
|
||||
if (eax == 5) {
|
||||
vm_set_capability(ctx, *pvcpu, VM_CAP_MTRAP_EXIT, 1);
|
||||
}
|
||||
}
|
||||
#if BHYVE_DEBUG
|
||||
/*
|
||||
* put guest-driven debug here
|
||||
*/
|
||||
#endif
|
||||
return (VMEXIT_CONTINUE);
|
||||
}
|
||||
@ -337,11 +312,6 @@ vmexit_wrmsr(struct vmctx *ctx, struct vm_exit *vme, int *pvcpu)
|
||||
|
||||
newcpu = emulate_wrmsr(ctx, *pvcpu, vme->u.msr.code,vme->u.msr.wval);
|
||||
|
||||
if (guest_vcpu_mux && *pvcpu != newcpu) {
|
||||
retval = VMEXIT_SWITCH;
|
||||
*pvcpu = newcpu;
|
||||
}
|
||||
|
||||
return (retval);
|
||||
}
|
||||
|
||||
@ -354,11 +324,6 @@ vmexit_spinup_ap(struct vmctx *ctx, struct vm_exit *vme, int *pvcpu)
|
||||
newcpu = spinup_ap(ctx, *pvcpu,
|
||||
vme->u.spinup_ap.vcpu, vme->u.spinup_ap.rip);
|
||||
|
||||
if (guest_vcpu_mux && *pvcpu != newcpu) {
|
||||
retval = VMEXIT_SWITCH;
|
||||
*pvcpu = newcpu;
|
||||
}
|
||||
|
||||
return (retval);
|
||||
}
|
||||
|
||||
@ -378,58 +343,42 @@ vmexit_vmx(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu)
|
||||
return (VMEXIT_ABORT);
|
||||
}
|
||||
|
||||
static int bogus_noswitch = 1;
|
||||
|
||||
static int
|
||||
vmexit_bogus(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu)
|
||||
{
|
||||
|
||||
stats.vmexit_bogus++;
|
||||
|
||||
if (!guest_vcpu_mux || guest_ncpus == 1 || bogus_noswitch) {
|
||||
return (VMEXIT_RESTART);
|
||||
} else {
|
||||
stats.vmexit_bogus_switch++;
|
||||
vmexit->inst_length = 0;
|
||||
*pvcpu = -1;
|
||||
return (VMEXIT_SWITCH);
|
||||
}
|
||||
return (VMEXIT_RESTART);
|
||||
}
|
||||
|
||||
static int
|
||||
vmexit_hlt(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu)
|
||||
{
|
||||
stats.vmexit_hlt++;
|
||||
if (fbsdrun_muxed()) {
|
||||
*pvcpu = -1;
|
||||
return (VMEXIT_SWITCH);
|
||||
} else {
|
||||
/*
|
||||
* Just continue execution with the next instruction. We use
|
||||
* the HLT VM exit as a way to be friendly with the host
|
||||
* scheduler.
|
||||
*/
|
||||
return (VMEXIT_CONTINUE);
|
||||
}
|
||||
}
|
||||
|
||||
static int pause_noswitch;
|
||||
stats.vmexit_hlt++;
|
||||
|
||||
/*
|
||||
* Just continue execution with the next instruction. We use
|
||||
* the HLT VM exit as a way to be friendly with the host
|
||||
* scheduler.
|
||||
*/
|
||||
return (VMEXIT_CONTINUE);
|
||||
}
|
||||
|
||||
static int
|
||||
vmexit_pause(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu)
|
||||
{
|
||||
|
||||
stats.vmexit_pause++;
|
||||
|
||||
if (fbsdrun_muxed() && !pause_noswitch) {
|
||||
*pvcpu = -1;
|
||||
return (VMEXIT_SWITCH);
|
||||
} else {
|
||||
return (VMEXIT_CONTINUE);
|
||||
}
|
||||
return (VMEXIT_CONTINUE);
|
||||
}
|
||||
|
||||
static int
|
||||
vmexit_mtrap(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu)
|
||||
{
|
||||
|
||||
stats.vmexit_mtrap++;
|
||||
|
||||
return (VMEXIT_RESTART);
|
||||
@ -460,39 +409,6 @@ vmexit_paging(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu)
|
||||
return (VMEXIT_CONTINUE);
|
||||
}
|
||||
|
||||
static void
|
||||
sigalrm(int sig)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
setup_timeslice(void)
|
||||
{
|
||||
struct sigaction sa;
|
||||
struct itimerval itv;
|
||||
int error;
|
||||
|
||||
/*
|
||||
* Setup a realtime timer to generate a SIGALRM at a
|
||||
* frequency of 'guest_tslice' ticks per second.
|
||||
*/
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sa.sa_flags = 0;
|
||||
sa.sa_handler = sigalrm;
|
||||
|
||||
error = sigaction(SIGALRM, &sa, NULL);
|
||||
assert(error == 0);
|
||||
|
||||
itv.it_interval.tv_sec = 0;
|
||||
itv.it_interval.tv_usec = 1000000 / guest_tslice;
|
||||
itv.it_value.tv_sec = 0;
|
||||
itv.it_value.tv_usec = 1000000 / guest_tslice;
|
||||
|
||||
error = setitimer(ITIMER_REAL, &itv, NULL);
|
||||
assert(error == 0);
|
||||
}
|
||||
|
||||
static vmexit_handler_t handler[VM_EXITCODE_MAX] = {
|
||||
[VM_EXITCODE_INOUT] = vmexit_inout,
|
||||
[VM_EXITCODE_VMX] = vmexit_vmx,
|
||||
@ -511,9 +427,6 @@ vm_loop(struct vmctx *ctx, int vcpu, uint64_t rip)
|
||||
int error, rc, prevcpu;
|
||||
enum vm_exitcode exitcode;
|
||||
|
||||
if (guest_vcpu_mux)
|
||||
setup_timeslice();
|
||||
|
||||
if (pincpu >= 0) {
|
||||
CPU_ZERO(&mask);
|
||||
CPU_SET(pincpu + vcpu, &mask);
|
||||
@ -550,15 +463,6 @@ vm_loop(struct vmctx *ctx, int vcpu, uint64_t rip)
|
||||
rc = (*handler[exitcode])(ctx, &vmexit[vcpu], &vcpu);
|
||||
|
||||
switch (rc) {
|
||||
case VMEXIT_SWITCH:
|
||||
assert(guest_vcpu_mux);
|
||||
if (vcpu == -1) {
|
||||
stats.cpu_switch_rotate++;
|
||||
vcpu = fbsdrun_get_next_cpu(prevcpu);
|
||||
} else {
|
||||
stats.cpu_switch_direct++;
|
||||
}
|
||||
/* fall through */
|
||||
case VMEXIT_CONTINUE:
|
||||
rip = vmexit[vcpu].rip + vmexit[vcpu].inst_length;
|
||||
break;
|
||||
@ -594,21 +498,20 @@ num_vcpus_allowed(struct vmctx *ctx)
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int c, error, gdb_port, inject_bkpt, tmp, err, ioapic, bvmcons;
|
||||
int c, error, gdb_port, tmp, err, ioapic, bvmcons;
|
||||
int max_vcpus;
|
||||
struct vmctx *ctx;
|
||||
uint64_t rip;
|
||||
size_t memsize;
|
||||
|
||||
bvmcons = 0;
|
||||
inject_bkpt = 0;
|
||||
progname = basename(argv[0]);
|
||||
gdb_port = DEFAULT_GDB_PORT;
|
||||
guest_ncpus = 1;
|
||||
ioapic = 0;
|
||||
memsize = 256 * MB;
|
||||
|
||||
while ((c = getopt(argc, argv, "abehABHIPxp:g:c:z:s:S:n:m:")) != -1) {
|
||||
while ((c = getopt(argc, argv, "abehAHIPp:g:c:s:S:m:")) != -1) {
|
||||
switch (c) {
|
||||
case 'a':
|
||||
disable_x2apic = 1;
|
||||
@ -619,12 +522,6 @@ main(int argc, char *argv[])
|
||||
case 'b':
|
||||
bvmcons = 1;
|
||||
break;
|
||||
case 'B':
|
||||
inject_bkpt = 1;
|
||||
break;
|
||||
case 'x':
|
||||
guest_vcpu_mux = 1;
|
||||
break;
|
||||
case 'p':
|
||||
pincpu = atoi(optarg);
|
||||
break;
|
||||
@ -634,12 +531,6 @@ main(int argc, char *argv[])
|
||||
case 'g':
|
||||
gdb_port = atoi(optarg);
|
||||
break;
|
||||
case 'z':
|
||||
guest_hz = atoi(optarg);
|
||||
break;
|
||||
case 't':
|
||||
guest_tslice = atoi(optarg);
|
||||
break;
|
||||
case 's':
|
||||
if (pci_parse_slot(optarg, 0) != 0)
|
||||
exit(1);
|
||||
@ -677,16 +568,6 @@ main(int argc, char *argv[])
|
||||
if (argc != 1)
|
||||
usage(1);
|
||||
|
||||
/* No need to mux if guest is uni-processor */
|
||||
if (guest_ncpus <= 1)
|
||||
guest_vcpu_mux = 0;
|
||||
|
||||
/* vmexit on hlt if guest is muxed */
|
||||
if (guest_vcpu_mux) {
|
||||
guest_vmexit_on_hlt = 1;
|
||||
guest_vmexit_on_pause = 1;
|
||||
}
|
||||
|
||||
vmname = argv[0];
|
||||
|
||||
ctx = vm_open(vmname);
|
||||
@ -765,11 +646,6 @@ main(int argc, char *argv[])
|
||||
error = vm_get_register(ctx, BSP, VM_REG_GUEST_RIP, &rip);
|
||||
assert(error == 0);
|
||||
|
||||
if (inject_bkpt) {
|
||||
error = vm_inject_event(ctx, BSP, VM_HW_EXCEPTION, IDT_BP);
|
||||
assert(error == 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* build the guest tables, MP etc.
|
||||
*/
|
||||
|
@ -36,8 +36,6 @@
|
||||
#endif
|
||||
|
||||
struct vmctx;
|
||||
extern int guest_hz;
|
||||
extern int guest_tslice;
|
||||
extern int guest_ncpus;
|
||||
extern char *vmname;
|
||||
|
||||
|
426
usr.sbin/bhyve/block_if.c
Normal file
426
usr.sbin/bhyve/block_if.c
Normal file
@ -0,0 +1,426 @@
|
||||
/*-
|
||||
* Copyright (c) 2013 Peter Grehan <grehan@freebsd.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 ``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$
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/disk.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
#include <pthread_np.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "bhyverun.h"
|
||||
#include "block_if.h"
|
||||
|
||||
#define BLOCKIF_SIG 0xb109b109
|
||||
|
||||
#define BLOCKIF_MAXREQ 16
|
||||
|
||||
enum blockop {
|
||||
BOP_READ,
|
||||
BOP_WRITE,
|
||||
BOP_FLUSH,
|
||||
BOP_CANCEL
|
||||
};
|
||||
|
||||
enum blockstat {
|
||||
BST_FREE,
|
||||
BST_INUSE
|
||||
};
|
||||
|
||||
struct blockif_elem {
|
||||
TAILQ_ENTRY(blockif_elem) be_link;
|
||||
struct blockif_req *be_req;
|
||||
enum blockop be_op;
|
||||
enum blockstat be_status;
|
||||
};
|
||||
|
||||
struct blockif_ctxt {
|
||||
int bc_magic;
|
||||
int bc_fd;
|
||||
int bc_rdonly;
|
||||
off_t bc_size;
|
||||
int bc_sectsz;
|
||||
pthread_t bc_btid;
|
||||
pthread_mutex_t bc_mtx;
|
||||
pthread_cond_t bc_cond;
|
||||
int bc_closing;
|
||||
|
||||
/* Request elements and free/inuse queues */
|
||||
TAILQ_HEAD(, blockif_elem) bc_freeq;
|
||||
TAILQ_HEAD(, blockif_elem) bc_inuseq;
|
||||
u_int bc_req_count;
|
||||
struct blockif_elem bc_reqs[BLOCKIF_MAXREQ];
|
||||
};
|
||||
|
||||
static int
|
||||
blockif_enqueue(struct blockif_ctxt *bc, struct blockif_req *breq,
|
||||
enum blockop op)
|
||||
{
|
||||
struct blockif_elem *be;
|
||||
|
||||
assert(bc->bc_req_count < BLOCKIF_MAXREQ);
|
||||
|
||||
be = TAILQ_FIRST(&bc->bc_freeq);
|
||||
assert(be != NULL);
|
||||
assert(be->be_status == BST_FREE);
|
||||
|
||||
TAILQ_REMOVE(&bc->bc_freeq, be, be_link);
|
||||
be->be_status = BST_INUSE;
|
||||
be->be_req = breq;
|
||||
be->be_op = op;
|
||||
TAILQ_INSERT_TAIL(&bc->bc_inuseq, be, be_link);
|
||||
|
||||
bc->bc_req_count++;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
blockif_dequeue(struct blockif_ctxt *bc, struct blockif_elem *el)
|
||||
{
|
||||
struct blockif_elem *be;
|
||||
|
||||
if (bc->bc_req_count == 0)
|
||||
return (ENOENT);
|
||||
|
||||
be = TAILQ_FIRST(&bc->bc_inuseq);
|
||||
assert(be != NULL);
|
||||
assert(be->be_status == BST_INUSE);
|
||||
*el = *be;
|
||||
|
||||
TAILQ_REMOVE(&bc->bc_inuseq, be, be_link);
|
||||
be->be_status = BST_FREE;
|
||||
be->be_req = NULL;
|
||||
TAILQ_INSERT_TAIL(&bc->bc_freeq, be, be_link);
|
||||
|
||||
bc->bc_req_count--;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
blockif_proc(struct blockif_ctxt *bc, struct blockif_elem *be)
|
||||
{
|
||||
struct blockif_req *br;
|
||||
int err;
|
||||
|
||||
br = be->be_req;
|
||||
err = 0;
|
||||
|
||||
switch (be->be_op) {
|
||||
case BOP_READ:
|
||||
if (preadv(bc->bc_fd, br->br_iov, br->br_iovcnt,
|
||||
br->br_offset) < 0)
|
||||
err = errno;
|
||||
break;
|
||||
case BOP_WRITE:
|
||||
if (bc->bc_rdonly)
|
||||
err = EROFS;
|
||||
else if (pwritev(bc->bc_fd, br->br_iov, br->br_iovcnt,
|
||||
br->br_offset) < 0)
|
||||
err = errno;
|
||||
break;
|
||||
case BOP_FLUSH:
|
||||
break;
|
||||
case BOP_CANCEL:
|
||||
err = EINTR;
|
||||
break;
|
||||
default:
|
||||
err = EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
(*br->br_callback)(br, err);
|
||||
}
|
||||
|
||||
static void *
|
||||
blockif_thr(void *arg)
|
||||
{
|
||||
struct blockif_ctxt *bc;
|
||||
struct blockif_elem req;
|
||||
|
||||
bc = arg;
|
||||
|
||||
for (;;) {
|
||||
pthread_mutex_lock(&bc->bc_mtx);
|
||||
while (!blockif_dequeue(bc, &req)) {
|
||||
pthread_mutex_unlock(&bc->bc_mtx);
|
||||
blockif_proc(bc, &req);
|
||||
pthread_mutex_lock(&bc->bc_mtx);
|
||||
}
|
||||
pthread_cond_wait(&bc->bc_cond, &bc->bc_mtx);
|
||||
pthread_mutex_unlock(&bc->bc_mtx);
|
||||
|
||||
/*
|
||||
* Check ctxt status here to see if exit requested
|
||||
*/
|
||||
if (bc->bc_closing)
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
/* Not reached */
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
struct blockif_ctxt *
|
||||
blockif_open(const char *optstr, const char *ident)
|
||||
{
|
||||
char tname[MAXCOMLEN + 1];
|
||||
char *nopt, *xopts;
|
||||
struct blockif_ctxt *bc;
|
||||
struct stat sbuf;
|
||||
off_t size;
|
||||
int extra, fd, i, sectsz;
|
||||
int nocache, sync, ro;
|
||||
|
||||
nocache = 0;
|
||||
sync = 0;
|
||||
ro = 0;
|
||||
|
||||
/*
|
||||
* The first element in the optstring is always a pathname.
|
||||
* Optional elements follow
|
||||
*/
|
||||
nopt = strdup(optstr);
|
||||
for (xopts = strtok(nopt, ",");
|
||||
xopts != NULL;
|
||||
xopts = strtok(NULL, ",")) {
|
||||
if (!strcmp(xopts, "nocache"))
|
||||
nocache = 1;
|
||||
else if (!strcmp(xopts, "sync"))
|
||||
sync = 1;
|
||||
else if (!strcmp(xopts, "ro"))
|
||||
ro = 1;
|
||||
}
|
||||
|
||||
extra = 0;
|
||||
if (nocache)
|
||||
extra |= O_DIRECT;
|
||||
if (sync)
|
||||
extra |= O_SYNC;
|
||||
|
||||
fd = open(nopt, (ro ? O_RDONLY : O_RDWR) | extra);
|
||||
if (fd < 0 && !ro) {
|
||||
/* Attempt a r/w fail with a r/o open */
|
||||
fd = open(nopt, O_RDONLY | extra);
|
||||
ro = 1;
|
||||
}
|
||||
|
||||
if (fd < 0) {
|
||||
perror("Could not open backing file");
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (fstat(fd, &sbuf) < 0) {
|
||||
perror("Could not stat backing file");
|
||||
close(fd);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Deal with raw devices
|
||||
*/
|
||||
size = sbuf.st_size;
|
||||
sectsz = DEV_BSIZE;
|
||||
if (S_ISCHR(sbuf.st_mode)) {
|
||||
if (ioctl(fd, DIOCGMEDIASIZE, &size) < 0 ||
|
||||
ioctl(fd, DIOCGSECTORSIZE, §sz)) {
|
||||
perror("Could not fetch dev blk/sector size");
|
||||
close(fd);
|
||||
return (NULL);
|
||||
}
|
||||
assert(size != 0);
|
||||
assert(sectsz != 0);
|
||||
}
|
||||
|
||||
bc = malloc(sizeof(struct blockif_ctxt));
|
||||
if (bc == NULL) {
|
||||
close(fd);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
memset(bc, 0, sizeof(*bc));
|
||||
bc->bc_magic = BLOCKIF_SIG;
|
||||
bc->bc_fd = fd;
|
||||
bc->bc_size = size;
|
||||
bc->bc_sectsz = sectsz;
|
||||
pthread_mutex_init(&bc->bc_mtx, NULL);
|
||||
pthread_cond_init(&bc->bc_cond, NULL);
|
||||
TAILQ_INIT(&bc->bc_freeq);
|
||||
TAILQ_INIT(&bc->bc_inuseq);
|
||||
bc->bc_req_count = 0;
|
||||
for (i = 0; i < BLOCKIF_MAXREQ; i++) {
|
||||
bc->bc_reqs[i].be_status = BST_FREE;
|
||||
TAILQ_INSERT_HEAD(&bc->bc_freeq, &bc->bc_reqs[i], be_link);
|
||||
}
|
||||
|
||||
pthread_create(&bc->bc_btid, NULL, blockif_thr, bc);
|
||||
|
||||
snprintf(tname, sizeof(tname), "%s blk-%s", vmname, ident);
|
||||
pthread_set_name_np(bc->bc_btid, tname);
|
||||
|
||||
return (bc);
|
||||
}
|
||||
|
||||
static int
|
||||
blockif_request(struct blockif_ctxt *bc, struct blockif_req *breq,
|
||||
enum blockop op)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = 0;
|
||||
|
||||
pthread_mutex_lock(&bc->bc_mtx);
|
||||
if (bc->bc_req_count < BLOCKIF_MAXREQ) {
|
||||
/*
|
||||
* Enqueue and inform the block i/o thread
|
||||
* that there is work available
|
||||
*/
|
||||
blockif_enqueue(bc, breq, op);
|
||||
pthread_cond_signal(&bc->bc_cond);
|
||||
} else {
|
||||
/*
|
||||
* Callers are not allowed to enqueue more than
|
||||
* the specified blockif queue limit. Return an
|
||||
* error to indicate that the queue length has been
|
||||
* exceeded.
|
||||
*/
|
||||
err = E2BIG;
|
||||
}
|
||||
pthread_mutex_unlock(&bc->bc_mtx);
|
||||
|
||||
return (err);
|
||||
}
|
||||
|
||||
int
|
||||
blockif_read(struct blockif_ctxt *bc, struct blockif_req *breq)
|
||||
{
|
||||
|
||||
assert(bc->bc_magic == BLOCKIF_SIG);
|
||||
return (blockif_request(bc, breq, BOP_READ));
|
||||
}
|
||||
|
||||
int
|
||||
blockif_write(struct blockif_ctxt *bc, struct blockif_req *breq)
|
||||
{
|
||||
|
||||
assert(bc->bc_magic == BLOCKIF_SIG);
|
||||
return (blockif_request(bc, breq, BOP_WRITE));
|
||||
}
|
||||
|
||||
int
|
||||
blockif_flush(struct blockif_ctxt *bc, struct blockif_req *breq)
|
||||
{
|
||||
|
||||
assert(bc->bc_magic == BLOCKIF_SIG);
|
||||
return (blockif_request(bc, breq, BOP_FLUSH));
|
||||
}
|
||||
|
||||
int
|
||||
blockif_cancel(struct blockif_ctxt *bc, struct blockif_req *breq)
|
||||
{
|
||||
|
||||
assert(bc->bc_magic == BLOCKIF_SIG);
|
||||
return (blockif_request(bc, breq, BOP_CANCEL));
|
||||
}
|
||||
|
||||
int
|
||||
blockif_close(struct blockif_ctxt *bc)
|
||||
{
|
||||
void *jval;
|
||||
int err;
|
||||
|
||||
err = 0;
|
||||
|
||||
assert(bc->bc_magic == BLOCKIF_SIG);
|
||||
|
||||
/*
|
||||
* Stop the block i/o thread
|
||||
*/
|
||||
bc->bc_closing = 1;
|
||||
pthread_cond_signal(&bc->bc_cond);
|
||||
pthread_join(bc->bc_btid, &jval);
|
||||
|
||||
/* XXX Cancel queued i/o's ??? */
|
||||
|
||||
/*
|
||||
* Release resources
|
||||
*/
|
||||
bc->bc_magic = 0;
|
||||
close(bc->bc_fd);
|
||||
free(bc);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Accessors
|
||||
*/
|
||||
off_t
|
||||
blockif_size(struct blockif_ctxt *bc)
|
||||
{
|
||||
|
||||
assert(bc->bc_magic == BLOCKIF_SIG);
|
||||
return (bc->bc_size);
|
||||
}
|
||||
|
||||
int
|
||||
blockif_sectsz(struct blockif_ctxt *bc)
|
||||
{
|
||||
|
||||
assert(bc->bc_magic == BLOCKIF_SIG);
|
||||
return (bc->bc_sectsz);
|
||||
}
|
||||
|
||||
int
|
||||
blockif_queuesz(struct blockif_ctxt *bc)
|
||||
{
|
||||
|
||||
assert(bc->bc_magic == BLOCKIF_SIG);
|
||||
return (BLOCKIF_MAXREQ);
|
||||
}
|
||||
|
||||
int
|
||||
blockif_is_ro(struct blockif_ctxt *bc)
|
||||
{
|
||||
|
||||
assert(bc->bc_magic == BLOCKIF_SIG);
|
||||
return (bc->bc_rdonly);
|
||||
}
|
64
usr.sbin/bhyve/block_if.h
Normal file
64
usr.sbin/bhyve/block_if.h
Normal file
@ -0,0 +1,64 @@
|
||||
/*-
|
||||
* Copyright (c) 2013 Peter Grehan <grehan@freebsd.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 ``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$
|
||||
*/
|
||||
|
||||
/*
|
||||
* The block API to be used by bhyve block-device emulations. The routines
|
||||
* are thread safe, with no assumptions about the context of the completion
|
||||
* callback - it may occur in the caller's context, or asynchronously in
|
||||
* another thread.
|
||||
*/
|
||||
|
||||
#ifndef _BLOCK_IF_H_
|
||||
#define _BLOCK_IF_H_
|
||||
|
||||
#include <sys/uio.h>
|
||||
#include <sys/unistd.h>
|
||||
|
||||
#define BLOCKIF_IOV_MAX 32 /* not practical to be IOV_MAX */
|
||||
|
||||
struct blockif_req {
|
||||
struct iovec br_iov[BLOCKIF_IOV_MAX];
|
||||
int br_iovcnt;
|
||||
off_t br_offset;
|
||||
void (*br_callback)(struct blockif_req *req, int err);
|
||||
void *br_param;
|
||||
};
|
||||
|
||||
struct blockif_ctxt;
|
||||
struct blockif_ctxt *blockif_open(const char *optstr, const char *ident);
|
||||
off_t blockif_size(struct blockif_ctxt *bc);
|
||||
int blockif_sectsz(struct blockif_ctxt *bc);
|
||||
int blockif_queuesz(struct blockif_ctxt *bc);
|
||||
int blockif_is_ro(struct blockif_ctxt *bc);
|
||||
int blockif_read(struct blockif_ctxt *bc, struct blockif_req *breq);
|
||||
int blockif_write(struct blockif_ctxt *bc, struct blockif_req *breq);
|
||||
int blockif_flush(struct blockif_ctxt *bc, struct blockif_req *breq);
|
||||
int blockif_cancel(struct blockif_ctxt *bc, struct blockif_req *breq);
|
||||
int blockif_close(struct blockif_ctxt *bc);
|
||||
|
||||
#endif /* _BLOCK_IF_H_ */
|
1805
usr.sbin/bhyve/pci_ahci.c
Normal file
1805
usr.sbin/bhyve/pci_ahci.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -153,10 +153,10 @@ pit_update_counter(struct counter *c, int latch)
|
||||
* of the program.
|
||||
*
|
||||
* If the counter's initial value is not programmed we
|
||||
* assume a value that would be set to generate 'guest_hz'
|
||||
* assume a value that would be set to generate 100
|
||||
* interrupts per second.
|
||||
*/
|
||||
c->initial = TIMER_DIV(PIT_8254_FREQ, guest_hz);
|
||||
c->initial = TIMER_DIV(PIT_8254_FREQ, 100);
|
||||
gettimeofday(&c->tv, NULL);
|
||||
}
|
||||
|
||||
|
@ -274,6 +274,16 @@ usage(void)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int
|
||||
compare(const FTSENT *const *a, const FTSENT *const *b)
|
||||
{
|
||||
if ((*a)->fts_info == FTS_D && (*b)->fts_info != FTS_D)
|
||||
return 1;
|
||||
if ((*a)->fts_info != FTS_D && (*b)->fts_info == FTS_D)
|
||||
return -1;
|
||||
return strcmp((*a)->fts_name, (*b)->fts_name);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
@ -315,7 +325,7 @@ main(int argc, char *argv[])
|
||||
err(1, "%s", argv[0]);
|
||||
}
|
||||
|
||||
ftsp = fts_open(argv, fts_options, 0);
|
||||
ftsp = fts_open(argv, fts_options, compare);
|
||||
if (ftsp == NULL)
|
||||
exit(1);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user