1 /*- 2 * Copyright (c) 2009-2016 Microsoft Corp. 3 * Copyright (c) 2012 NetApp Inc. 4 * Copyright (c) 2012 Citrix Inc. 5 * Copyright (c) 2016 Mike Belopuhov <mike@esdenera.com> 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice unmodified, this list of conditions, and the following 13 * disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 /* 31 * The OpenBSD port was done under funding by Esdenera Networks GmbH. 32 */ 33 34 #include <sys/param.h> 35 36 /* Hyperv requires locked atomic operations */ 37 #ifndef MULTIPROCESSOR 38 #define _HYPERVMPATOMICS 39 #define MULTIPROCESSOR 40 #endif 41 #include <sys/atomic.h> 42 #ifdef _HYPERVMPATOMICS 43 #undef MULTIPROCESSOR 44 #undef _HYPERVMPATOMICS 45 #endif 46 47 #include <sys/systm.h> 48 #include <sys/malloc.h> 49 #include <sys/kernel.h> 50 #include <sys/device.h> 51 #include <sys/pool.h> 52 #include <sys/task.h> 53 #include <sys/sensors.h> 54 55 #include <machine/bus.h> 56 57 #include <net/if.h> 58 #include <net/if_dl.h> 59 #include <netinet/in.h> 60 #include <netinet/if_ether.h> 61 62 #include <dev/pv/pvvar.h> 63 #include <dev/pv/hypervreg.h> 64 #include <dev/pv/hypervvar.h> 65 #include <dev/pv/hypervicreg.h> 66 67 struct hv_ic_dev; 68 69 #define NKVPPOOLS 4 70 #define MAXPOOLENTS 1023 71 72 struct kvp_entry { 73 int kpe_index; 74 uint32_t kpe_valtype; 75 uint8_t kpe_key[HV_KVP_MAX_KEY_SIZE / 2]; 76 uint8_t kpe_val[HV_KVP_MAX_VAL_SIZE / 2]; 77 TAILQ_ENTRY(kvp_entry) kpe_entry; 78 }; 79 TAILQ_HEAD(kvp_list, kvp_entry); 80 81 struct kvp_pool { 82 struct kvp_list kvp_entries; 83 struct mutex kvp_lock; 84 u_int kvp_index; 85 }; 86 87 struct pool kvp_entry_pool; 88 89 struct hv_kvp { 90 struct kvp_pool kvp_pool[NKVPPOOLS]; 91 }; 92 93 int hv_heartbeat_attach(struct hv_ic_dev *); 94 void hv_heartbeat(void *); 95 int hv_kvp_attach(struct hv_ic_dev *); 96 void hv_kvp(void *); 97 int hv_kvop(void *, int, char *, char *, size_t); 98 int hv_shutdown_attach(struct hv_ic_dev *); 99 void hv_shutdown(void *); 100 int hv_timesync_attach(struct hv_ic_dev *); 101 void hv_timesync(void *); 102 103 static struct hv_ic_dev { 104 const char *dv_name; 105 const struct hv_guid *dv_type; 106 int (*dv_attach)(struct hv_ic_dev *); 107 void (*dv_handler)(void *); 108 struct hv_channel *dv_ch; 109 uint8_t *dv_buf; 110 void *dv_priv; 111 } hv_ic_devs[] = { 112 { 113 "heartbeat", 114 &hv_guid_heartbeat, 115 hv_heartbeat_attach, 116 hv_heartbeat 117 }, 118 { 119 "kvp", 120 &hv_guid_kvp, 121 hv_kvp_attach, 122 hv_kvp 123 }, 124 { 125 "shutdown", 126 &hv_guid_shutdown, 127 hv_shutdown_attach, 128 hv_shutdown 129 }, 130 { 131 "timesync", 132 &hv_guid_timesync, 133 hv_timesync_attach, 134 hv_timesync 135 } 136 }; 137 138 static const struct { 139 enum hv_kvp_pool poolidx; 140 const char *poolname; 141 size_t poolnamelen; 142 } kvp_pools[] = { 143 { HV_KVP_POOL_EXTERNAL, "External", sizeof("External") }, 144 { HV_KVP_POOL_GUEST, "Guest", sizeof("Guest") }, 145 { HV_KVP_POOL_AUTO, "Auto", sizeof("Auto") }, 146 { HV_KVP_POOL_AUTO_EXTERNAL, "Guest/Parameters", 147 sizeof("Guest/Parameters") } 148 }; 149 150 static const struct { 151 int keyidx; 152 const char *keyname; 153 const char *value; 154 } kvp_pool_auto[] = { 155 { 0, "FullyQualifiedDomainName", hostname }, 156 { 1, "IntegrationServicesVersion", "6.6.6" }, 157 { 2, "NetworkAddressIPv4", "127.0.0.1" }, 158 { 3, "NetworkAddressIPv6", "::1" }, 159 { 4, "OSBuildNumber", osversion }, 160 { 5, "OSName", ostype }, 161 { 6, "OSMajorVersion", "6" }, /* free commit for mike */ 162 { 7, "OSMinorVersion", &osrelease[2] }, 163 { 8, "OSVersion", osrelease }, 164 #ifdef __amd64__ /* As specified in SYSTEM_INFO.wProcessorArchitecture */ 165 { 9, "ProcessorArchitecture", "9" } 166 #else 167 { 9, "ProcessorArchitecture", "0" } 168 #endif 169 }; 170 171 void 172 hv_attach_icdevs(struct hv_softc *sc) 173 { 174 struct hv_ic_dev *dv; 175 struct hv_channel *ch; 176 int i, header = 0; 177 178 for (i = 0; i < nitems(hv_ic_devs); i++) { 179 dv = &hv_ic_devs[i]; 180 181 TAILQ_FOREACH(ch, &sc->sc_channels, ch_entry) { 182 if (ch->ch_state != HV_CHANSTATE_OFFERED) 183 continue; 184 if (ch->ch_flags & CHF_MONITOR) 185 continue; 186 if (memcmp(dv->dv_type, &ch->ch_type, 187 sizeof(ch->ch_type)) == 0) 188 break; 189 } 190 if (ch == NULL) 191 continue; 192 193 dv->dv_ch = ch; 194 195 /* 196 * These services are not performance critical and 197 * do not need batched reading. Furthermore, some 198 * services such as KVP can only handle one message 199 * from the host at a time. 200 */ 201 dv->dv_ch->ch_flags &= ~CHF_BATCHED; 202 203 if (dv->dv_attach && dv->dv_attach(dv) != 0) 204 continue; 205 206 if (hv_channel_open(ch, VMBUS_IC_BUFRINGSIZE, NULL, 0, 207 dv->dv_handler, dv)) { 208 printf("%s: failed to open channel for %s\n", 209 sc->sc_dev.dv_xname, dv->dv_name); 210 continue; 211 } 212 evcount_attach(&ch->ch_evcnt, dv->dv_name, &sc->sc_idtvec); 213 214 if (!header) { 215 printf("%s: %s", sc->sc_dev.dv_xname, dv->dv_name); 216 header = 1; 217 } else 218 printf(", %s", dv->dv_name); 219 } 220 if (header) 221 printf("\n"); 222 } 223 224 static inline void 225 hv_ic_negotiate(struct vmbus_icmsg_hdr *hdr, uint32_t *rlen, uint32_t fwver, 226 uint32_t msgver) 227 { 228 struct vmbus_icmsg_negotiate *msg; 229 uint16_t propmin, propmaj, chosenmaj, chosenmin; 230 int i; 231 232 msg = (struct vmbus_icmsg_negotiate *)hdr; 233 234 chosenmaj = chosenmin = 0; 235 for (i = 0; i < msg->ic_fwver_cnt; i++) { 236 propmaj = VMBUS_ICVER_MAJOR(msg->ic_ver[i]); 237 propmin = VMBUS_ICVER_MINOR(msg->ic_ver[i]); 238 if (propmaj > chosenmaj && 239 propmaj <= VMBUS_ICVER_MAJOR(fwver) && 240 propmin >= chosenmin && 241 propmin <= VMBUS_ICVER_MINOR(fwver)) { 242 chosenmaj = propmaj; 243 chosenmin = propmin; 244 } 245 } 246 fwver = VMBUS_IC_VERSION(chosenmaj, chosenmin); 247 248 chosenmaj = chosenmin = 0; 249 for (; i < msg->ic_fwver_cnt + msg->ic_msgver_cnt; i++) { 250 propmaj = VMBUS_ICVER_MAJOR(msg->ic_ver[i]); 251 propmin = VMBUS_ICVER_MINOR(msg->ic_ver[i]); 252 if (propmaj > chosenmaj && 253 propmaj <= VMBUS_ICVER_MAJOR(msgver) && 254 propmin >= chosenmin && 255 propmin <= VMBUS_ICVER_MINOR(msgver)) { 256 chosenmaj = propmaj; 257 chosenmin = propmin; 258 } 259 } 260 msgver = VMBUS_IC_VERSION(chosenmaj, chosenmin); 261 262 msg->ic_fwver_cnt = 1; 263 msg->ic_ver[0] = fwver; 264 msg->ic_msgver_cnt = 1; 265 msg->ic_ver[1] = msgver; 266 hdr->ic_dsize = sizeof(*msg) + 2 * sizeof(uint32_t) - 267 sizeof(struct vmbus_icmsg_hdr); 268 if (*rlen < sizeof(*msg) + 2 * sizeof(uint32_t)) 269 *rlen = sizeof(*msg) + 2 * sizeof(uint32_t); 270 } 271 272 int 273 hv_heartbeat_attach(struct hv_ic_dev *dv) 274 { 275 struct hv_channel *ch = dv->dv_ch; 276 struct hv_softc *sc = ch->ch_sc; 277 278 dv->dv_buf = malloc(PAGE_SIZE, M_DEVBUF, M_ZERO | 279 (cold ? M_NOWAIT : M_WAITOK)); 280 if (dv->dv_buf == NULL) { 281 printf("%s: failed to allocate receive buffer\n", 282 sc->sc_dev.dv_xname); 283 return (-1); 284 } 285 return (0); 286 } 287 288 void 289 hv_heartbeat(void *arg) 290 { 291 struct hv_ic_dev *dv = arg; 292 struct hv_channel *ch = dv->dv_ch; 293 struct hv_softc *sc = ch->ch_sc; 294 struct vmbus_icmsg_hdr *hdr; 295 struct vmbus_icmsg_heartbeat *msg; 296 uint64_t rid; 297 uint32_t rlen; 298 int rv; 299 300 rv = hv_channel_recv(ch, dv->dv_buf, PAGE_SIZE, &rlen, &rid, 0); 301 if (rv || rlen == 0) { 302 if (rv != EAGAIN) 303 DPRINTF("%s: heartbeat rv=%d rlen=%u\n", 304 sc->sc_dev.dv_xname, rv, rlen); 305 return; 306 } 307 if (rlen < sizeof(struct vmbus_icmsg_hdr)) { 308 DPRINTF("%s: heartbeat short read rlen=%u\n", 309 sc->sc_dev.dv_xname, rlen); 310 return; 311 } 312 hdr = (struct vmbus_icmsg_hdr *)dv->dv_buf; 313 switch (hdr->ic_type) { 314 case VMBUS_ICMSG_TYPE_NEGOTIATE: 315 hv_ic_negotiate(hdr, &rlen, VMBUS_IC_VERSION(3, 0), 316 VMBUS_IC_VERSION(3, 0)); 317 break; 318 case VMBUS_ICMSG_TYPE_HEARTBEAT: 319 msg = (struct vmbus_icmsg_heartbeat *)hdr; 320 msg->ic_seq += 1; 321 break; 322 default: 323 printf("%s: unhandled heartbeat message type %u\n", 324 sc->sc_dev.dv_xname, hdr->ic_type); 325 return; 326 } 327 hdr->ic_flags = VMBUS_ICMSG_FLAG_TRANSACTION | VMBUS_ICMSG_FLAG_RESPONSE; 328 hv_channel_send(ch, dv->dv_buf, rlen, rid, VMBUS_CHANPKT_TYPE_INBAND, 0); 329 } 330 331 static void 332 hv_shutdown_task(void *arg) 333 { 334 struct hv_softc *sc = arg; 335 pvbus_shutdown(&sc->sc_dev); 336 } 337 338 int 339 hv_shutdown_attach(struct hv_ic_dev *dv) 340 { 341 struct hv_channel *ch = dv->dv_ch; 342 struct hv_softc *sc = ch->ch_sc; 343 344 dv->dv_buf = malloc(PAGE_SIZE, M_DEVBUF, M_ZERO | 345 (cold ? M_NOWAIT : M_WAITOK)); 346 if (dv->dv_buf == NULL) { 347 printf("%s: failed to allocate receive buffer\n", 348 sc->sc_dev.dv_xname); 349 return (-1); 350 } 351 352 task_set(&sc->sc_sdtask, hv_shutdown_task, sc); 353 354 return (0); 355 } 356 357 void 358 hv_shutdown(void *arg) 359 { 360 struct hv_ic_dev *dv = arg; 361 struct hv_channel *ch = dv->dv_ch; 362 struct hv_softc *sc = ch->ch_sc; 363 struct vmbus_icmsg_hdr *hdr; 364 struct vmbus_icmsg_shutdown *msg; 365 uint64_t rid; 366 uint32_t rlen; 367 int rv, shutdown = 0; 368 369 rv = hv_channel_recv(ch, dv->dv_buf, PAGE_SIZE, &rlen, &rid, 0); 370 if (rv || rlen == 0) { 371 if (rv != EAGAIN) 372 DPRINTF("%s: shutdown rv=%d rlen=%u\n", 373 sc->sc_dev.dv_xname, rv, rlen); 374 return; 375 } 376 if (rlen < sizeof(struct vmbus_icmsg_hdr)) { 377 DPRINTF("%s: shutdown short read rlen=%u\n", 378 sc->sc_dev.dv_xname, rlen); 379 return; 380 } 381 hdr = (struct vmbus_icmsg_hdr *)dv->dv_buf; 382 switch (hdr->ic_type) { 383 case VMBUS_ICMSG_TYPE_NEGOTIATE: 384 hv_ic_negotiate(hdr, &rlen, VMBUS_IC_VERSION(3, 0), 385 VMBUS_IC_VERSION(3, 0)); 386 break; 387 case VMBUS_ICMSG_TYPE_SHUTDOWN: 388 msg = (struct vmbus_icmsg_shutdown *)hdr; 389 if (msg->ic_haltflags == 0 || msg->ic_haltflags == 1) { 390 shutdown = 1; 391 hdr->ic_status = VMBUS_ICMSG_STATUS_OK; 392 } else 393 hdr->ic_status = VMBUS_ICMSG_STATUS_FAIL; 394 break; 395 default: 396 printf("%s: unhandled shutdown message type %u\n", 397 sc->sc_dev.dv_xname, hdr->ic_type); 398 return; 399 } 400 401 hdr->ic_flags = VMBUS_ICMSG_FLAG_TRANSACTION | VMBUS_ICMSG_FLAG_RESPONSE; 402 hv_channel_send(ch, dv->dv_buf, rlen, rid, VMBUS_CHANPKT_TYPE_INBAND, 0); 403 404 if (shutdown) 405 task_add(systq, &sc->sc_sdtask); 406 } 407 408 int 409 hv_timesync_attach(struct hv_ic_dev *dv) 410 { 411 struct hv_channel *ch = dv->dv_ch; 412 struct hv_softc *sc = ch->ch_sc; 413 414 dv->dv_buf = malloc(PAGE_SIZE, M_DEVBUF, M_ZERO | 415 (cold ? M_NOWAIT : M_WAITOK)); 416 if (dv->dv_buf == NULL) { 417 printf("%s: failed to allocate receive buffer\n", 418 sc->sc_dev.dv_xname); 419 return (-1); 420 } 421 422 strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname, 423 sizeof(sc->sc_sensordev.xname)); 424 425 sc->sc_sensor.type = SENSOR_TIMEDELTA; 426 sc->sc_sensor.status = SENSOR_S_UNKNOWN; 427 428 sensor_attach(&sc->sc_sensordev, &sc->sc_sensor); 429 sensordev_install(&sc->sc_sensordev); 430 431 return (0); 432 } 433 434 void 435 hv_timesync(void *arg) 436 { 437 struct hv_ic_dev *dv = arg; 438 struct hv_channel *ch = dv->dv_ch; 439 struct hv_softc *sc = ch->ch_sc; 440 struct vmbus_icmsg_hdr *hdr; 441 struct vmbus_icmsg_timesync *msg; 442 struct timespec guest, host, diff; 443 uint64_t tns; 444 uint64_t rid; 445 uint32_t rlen; 446 int rv; 447 448 rv = hv_channel_recv(ch, dv->dv_buf, PAGE_SIZE, &rlen, &rid, 0); 449 if (rv || rlen == 0) { 450 if (rv != EAGAIN) 451 DPRINTF("%s: timesync rv=%d rlen=%u\n", 452 sc->sc_dev.dv_xname, rv, rlen); 453 return; 454 } 455 if (rlen < sizeof(struct vmbus_icmsg_hdr)) { 456 DPRINTF("%s: timesync short read rlen=%u\n", 457 sc->sc_dev.dv_xname, rlen); 458 return; 459 } 460 hdr = (struct vmbus_icmsg_hdr *)dv->dv_buf; 461 switch (hdr->ic_type) { 462 case VMBUS_ICMSG_TYPE_NEGOTIATE: 463 hv_ic_negotiate(hdr, &rlen, VMBUS_IC_VERSION(3, 0), 464 VMBUS_IC_VERSION(3, 0)); 465 break; 466 case VMBUS_ICMSG_TYPE_TIMESYNC: 467 msg = (struct vmbus_icmsg_timesync *)hdr; 468 if (msg->ic_tsflags == VMBUS_ICMSG_TS_FLAG_SAMPLE) { 469 microtime(&sc->sc_sensor.tv); 470 nanotime(&guest); 471 tns = (msg->ic_hvtime - 116444736000000000LL) * 100; 472 host.tv_sec = tns / 1000000000LL; 473 host.tv_nsec = tns % 1000000000LL; 474 timespecsub(&guest, &host, &diff); 475 sc->sc_sensor.value = (int64_t)diff.tv_sec * 476 1000000000LL + diff.tv_nsec; 477 sc->sc_sensor.status = SENSOR_S_OK; 478 } 479 break; 480 default: 481 printf("%s: unhandled timesync message type %u\n", 482 sc->sc_dev.dv_xname, hdr->ic_type); 483 return; 484 } 485 486 hdr->ic_flags = VMBUS_ICMSG_FLAG_TRANSACTION | VMBUS_ICMSG_FLAG_RESPONSE; 487 hv_channel_send(ch, dv->dv_buf, rlen, rid, VMBUS_CHANPKT_TYPE_INBAND, 0); 488 } 489 490 static inline int 491 copyout_utf16le(void *dst, const void *src, size_t dlen, size_t slen) 492 { 493 const uint8_t *sp = src; 494 uint8_t *dp = dst; 495 int i, j; 496 497 KASSERT(dlen >= slen * 2); 498 499 for (i = j = 0; i < slen; i++, j += 2) { 500 dp[j] = sp[i]; 501 dp[j + 1] = '\0'; 502 } 503 return (j); 504 } 505 506 static inline int 507 copyin_utf16le(void *dst, const void *src, size_t dlen, size_t slen) 508 { 509 const uint8_t *sp = src; 510 uint8_t *dp = dst; 511 int i, j; 512 513 KASSERT(dlen >= slen / 2); 514 515 for (i = j = 0; i < slen; i += 2, j++) 516 dp[j] = sp[i]; 517 return (j); 518 } 519 520 static inline int 521 keycmp_utf16le(const uint8_t *key, const uint8_t *ukey, size_t ukeylen) 522 { 523 int i, j; 524 525 for (i = j = 0; i < ukeylen; i += 2, j++) { 526 if (key[j] != ukey[i]) 527 return (key[j] > ukey[i] ? 528 key[j] - ukey[i] : 529 ukey[i] - key[j]); 530 } 531 return (0); 532 } 533 534 static void 535 kvp_pool_init(struct kvp_pool *kvpl) 536 { 537 TAILQ_INIT(&kvpl->kvp_entries); 538 mtx_init(&kvpl->kvp_lock, IPL_NET); 539 kvpl->kvp_index = 0; 540 } 541 542 static int 543 kvp_pool_insert(struct kvp_pool *kvpl, const char *key, const char *val, 544 uint32_t vallen, uint32_t valtype) 545 { 546 struct kvp_entry *kpe; 547 int keylen = strlen(key); 548 549 if (keylen > HV_KVP_MAX_KEY_SIZE / 2) 550 return (ERANGE); 551 552 mtx_enter(&kvpl->kvp_lock); 553 554 TAILQ_FOREACH(kpe, &kvpl->kvp_entries, kpe_entry) { 555 if (strcmp(kpe->kpe_key, key) == 0) { 556 mtx_leave(&kvpl->kvp_lock); 557 return (EEXIST); 558 } 559 } 560 561 kpe = pool_get(&kvp_entry_pool, PR_ZERO | PR_NOWAIT); 562 if (kpe == NULL) { 563 mtx_leave(&kvpl->kvp_lock); 564 return (ENOMEM); 565 } 566 567 strlcpy(kpe->kpe_key, key, HV_KVP_MAX_KEY_SIZE / 2); 568 569 if ((kpe->kpe_valtype = valtype) == HV_KVP_REG_SZ) 570 strlcpy(kpe->kpe_val, val, HV_KVP_MAX_KEY_SIZE / 2); 571 else 572 memcpy(kpe->kpe_val, val, vallen); 573 574 kpe->kpe_index = kvpl->kvp_index++ & MAXPOOLENTS; 575 576 TAILQ_INSERT_TAIL(&kvpl->kvp_entries, kpe, kpe_entry); 577 578 mtx_leave(&kvpl->kvp_lock); 579 580 return (0); 581 } 582 583 static int 584 kvp_pool_update(struct kvp_pool *kvpl, const char *key, const char *val, 585 uint32_t vallen, uint32_t valtype) 586 { 587 struct kvp_entry *kpe; 588 int keylen = strlen(key); 589 590 if (keylen > HV_KVP_MAX_KEY_SIZE / 2) 591 return (ERANGE); 592 593 mtx_enter(&kvpl->kvp_lock); 594 595 TAILQ_FOREACH(kpe, &kvpl->kvp_entries, kpe_entry) { 596 if (strcmp(kpe->kpe_key, key) == 0) 597 break; 598 } 599 if (kpe == NULL) { 600 mtx_leave(&kvpl->kvp_lock); 601 return (ENOENT); 602 } 603 604 if ((kpe->kpe_valtype = valtype) == HV_KVP_REG_SZ) 605 strlcpy(kpe->kpe_val, val, HV_KVP_MAX_KEY_SIZE / 2); 606 else 607 memcpy(kpe->kpe_val, val, vallen); 608 609 mtx_leave(&kvpl->kvp_lock); 610 611 return (0); 612 } 613 614 static int 615 kvp_pool_import(struct kvp_pool *kvpl, const char *key, uint32_t keylen, 616 const char *val, uint32_t vallen, uint32_t valtype) 617 { 618 struct kvp_entry *kpe; 619 620 if (keylen > HV_KVP_MAX_KEY_SIZE || 621 vallen > HV_KVP_MAX_VAL_SIZE) 622 return (ERANGE); 623 624 mtx_enter(&kvpl->kvp_lock); 625 626 TAILQ_FOREACH(kpe, &kvpl->kvp_entries, kpe_entry) { 627 if (keycmp_utf16le(kpe->kpe_key, key, keylen) == 0) 628 break; 629 } 630 if (kpe == NULL) { 631 kpe = pool_get(&kvp_entry_pool, PR_ZERO | PR_NOWAIT); 632 if (kpe == NULL) { 633 mtx_leave(&kvpl->kvp_lock); 634 return (ENOMEM); 635 } 636 637 copyin_utf16le(kpe->kpe_key, key, HV_KVP_MAX_KEY_SIZE / 2, 638 keylen); 639 640 kpe->kpe_index = kvpl->kvp_index++ & MAXPOOLENTS; 641 642 TAILQ_INSERT_TAIL(&kvpl->kvp_entries, kpe, kpe_entry); 643 } 644 645 copyin_utf16le(kpe->kpe_val, val, HV_KVP_MAX_VAL_SIZE / 2, vallen); 646 kpe->kpe_valtype = valtype; 647 648 mtx_leave(&kvpl->kvp_lock); 649 650 return (0); 651 } 652 653 static int 654 kvp_pool_export(struct kvp_pool *kvpl, uint32_t index, char *key, 655 uint32_t *keylen, char *val, uint32_t *vallen, uint32_t *valtype) 656 { 657 struct kvp_entry *kpe; 658 659 mtx_enter(&kvpl->kvp_lock); 660 661 TAILQ_FOREACH(kpe, &kvpl->kvp_entries, kpe_entry) { 662 if (kpe->kpe_index == index) 663 break; 664 } 665 if (kpe == NULL) { 666 mtx_leave(&kvpl->kvp_lock); 667 return (ENOENT); 668 } 669 670 *keylen = copyout_utf16le(key, kpe->kpe_key, HV_KVP_MAX_KEY_SIZE, 671 strlen(kpe->kpe_key) + 1); 672 *vallen = copyout_utf16le(val, kpe->kpe_val, HV_KVP_MAX_VAL_SIZE, 673 strlen(kpe->kpe_val) + 1); 674 *valtype = kpe->kpe_valtype; 675 676 mtx_leave(&kvpl->kvp_lock); 677 678 return (0); 679 } 680 681 static int 682 kvp_pool_remove(struct kvp_pool *kvpl, const char *key, uint32_t keylen) 683 { 684 struct kvp_entry *kpe; 685 686 mtx_enter(&kvpl->kvp_lock); 687 688 TAILQ_FOREACH(kpe, &kvpl->kvp_entries, kpe_entry) { 689 if (keycmp_utf16le(kpe->kpe_key, key, keylen) == 0) 690 break; 691 } 692 if (kpe == NULL) { 693 mtx_leave(&kvpl->kvp_lock); 694 return (ENOENT); 695 } 696 697 TAILQ_REMOVE(&kvpl->kvp_entries, kpe, kpe_entry); 698 699 mtx_leave(&kvpl->kvp_lock); 700 701 pool_put(&kvp_entry_pool, kpe); 702 703 return (0); 704 } 705 706 static int 707 kvp_pool_extract(struct kvp_pool *kvpl, const char *key, char *val, 708 uint32_t vallen) 709 { 710 struct kvp_entry *kpe; 711 712 if (vallen < HV_KVP_MAX_VAL_SIZE / 2) 713 return (ERANGE); 714 715 mtx_enter(&kvpl->kvp_lock); 716 717 TAILQ_FOREACH(kpe, &kvpl->kvp_entries, kpe_entry) { 718 if (strcmp(kpe->kpe_key, key) == 0) 719 break; 720 } 721 if (kpe == NULL) { 722 mtx_leave(&kvpl->kvp_lock); 723 return (ENOENT); 724 } 725 726 switch (kpe->kpe_valtype) { 727 case HV_KVP_REG_SZ: 728 strlcpy(val, kpe->kpe_val, HV_KVP_MAX_VAL_SIZE / 2); 729 break; 730 case HV_KVP_REG_U32: 731 snprintf(val, HV_KVP_MAX_VAL_SIZE / 2, "%u", 732 *(uint32_t *)kpe->kpe_val); 733 break; 734 case HV_KVP_REG_U64: 735 snprintf(val, HV_KVP_MAX_VAL_SIZE / 2, "%llu", 736 *(uint64_t *)kpe->kpe_val); 737 break; 738 } 739 740 mtx_leave(&kvpl->kvp_lock); 741 742 return (0); 743 } 744 745 static int 746 kvp_pool_keys(struct kvp_pool *kvpl, int next, char *key, size_t *keylen) 747 { 748 struct kvp_entry *kpe; 749 int iter = 0; 750 751 mtx_enter(&kvpl->kvp_lock); 752 753 TAILQ_FOREACH(kpe, &kvpl->kvp_entries, kpe_entry) { 754 if (iter++ < next) 755 continue; 756 *keylen = strlen(kpe->kpe_key) + 1; 757 strlcpy(key, kpe->kpe_key, *keylen); 758 759 mtx_leave(&kvpl->kvp_lock); 760 761 return (0); 762 } 763 764 mtx_leave(&kvpl->kvp_lock); 765 766 return (-1); 767 } 768 769 int 770 hv_kvp_attach(struct hv_ic_dev *dv) 771 { 772 struct hv_channel *ch = dv->dv_ch; 773 struct hv_softc *sc = ch->ch_sc; 774 struct hv_kvp *kvp; 775 int i; 776 777 dv->dv_buf = malloc(2 * PAGE_SIZE, M_DEVBUF, M_ZERO | 778 (cold ? M_NOWAIT : M_WAITOK)); 779 if (dv->dv_buf == NULL) { 780 printf("%s: failed to allocate receive buffer\n", 781 sc->sc_dev.dv_xname); 782 return (-1); 783 } 784 785 dv->dv_priv = malloc(sizeof(struct hv_kvp), M_DEVBUF, M_ZERO | 786 (cold ? M_NOWAIT : M_WAITOK)); 787 if (dv->dv_priv == NULL) { 788 free(dv->dv_buf, M_DEVBUF, 2 * PAGE_SIZE); 789 printf("%s: failed to allocate KVP private data\n", 790 sc->sc_dev.dv_xname); 791 return (-1); 792 } 793 kvp = dv->dv_priv; 794 795 pool_init(&kvp_entry_pool, sizeof(struct kvp_entry), 0, IPL_NET, 0, 796 "hvkvpl", NULL); 797 798 for (i = 0; i < NKVPPOOLS; i++) 799 kvp_pool_init(&kvp->kvp_pool[i]); 800 801 /* Initialize 'Auto' pool */ 802 for (i = 0; i < nitems(kvp_pool_auto); i++) { 803 if (kvp_pool_insert(&kvp->kvp_pool[HV_KVP_POOL_AUTO], 804 kvp_pool_auto[i].keyname, kvp_pool_auto[i].value, 805 strlen(kvp_pool_auto[i].value), HV_KVP_REG_SZ)) 806 DPRINTF("%s: failed to insert into 'Auto' pool\n", 807 sc->sc_dev.dv_xname); 808 } 809 810 sc->sc_pvbus->hv_kvop = hv_kvop; 811 sc->sc_pvbus->hv_arg = dv; 812 813 return (0); 814 } 815 816 static int 817 nibble(int ch) 818 { 819 if (ch >= '0' && ch <= '9') 820 return (ch - '0'); 821 if (ch >= 'A' && ch <= 'F') 822 return (10 + ch - 'A'); 823 if (ch >= 'a' && ch <= 'f') 824 return (10 + ch - 'a'); 825 return (-1); 826 } 827 828 static int 829 kvp_get_ip_info(struct hv_kvp *kvp, const uint8_t *mac, uint8_t *family, 830 uint8_t *addr, uint8_t *netmask, size_t addrlen) 831 { 832 struct ifnet *ifp; 833 struct ifaddr *ifa, *ifa6, *ifa6ll; 834 struct sockaddr_in *sin; 835 struct sockaddr_in6 *sin6, sa6; 836 uint8_t enaddr[ETHER_ADDR_LEN]; 837 uint8_t ipaddr[INET6_ADDRSTRLEN]; 838 int i, j, lo, hi, s, af; 839 840 /* Convert from the UTF-16LE string format to binary */ 841 for (i = 0, j = 0; j < ETHER_ADDR_LEN; i += 6) { 842 if ((hi = nibble(mac[i])) == -1 || 843 (lo = nibble(mac[i+2])) == -1) 844 return (-1); 845 enaddr[j++] = hi << 4 | lo; 846 } 847 848 switch (*family) { 849 case ADDR_FAMILY_NONE: 850 af = AF_UNSPEC; 851 break; 852 case ADDR_FAMILY_IPV4: 853 af = AF_INET; 854 break; 855 case ADDR_FAMILY_IPV6: 856 af = AF_INET6; 857 break; 858 default: 859 return (-1); 860 } 861 862 KERNEL_LOCK(); 863 s = splnet(); 864 865 TAILQ_FOREACH(ifp, &ifnetlist, if_list) { 866 if (!memcmp(LLADDR(ifp->if_sadl), enaddr, ETHER_ADDR_LEN)) 867 break; 868 } 869 if (ifp == NULL) { 870 splx(s); 871 KERNEL_UNLOCK(); 872 return (-1); 873 } 874 875 ifa6 = ifa6ll = NULL; 876 877 /* Try to find a best matching address, preferring IPv4 */ 878 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) { 879 /* 880 * First IPv4 address is always a best match unless 881 * we were asked for an IPv6 address. 882 */ 883 if ((af == AF_INET || af == AF_UNSPEC) && 884 (ifa->ifa_addr->sa_family == AF_INET)) { 885 af = AF_INET; 886 goto found; 887 } 888 if ((af == AF_INET6 || af == AF_UNSPEC) && 889 (ifa->ifa_addr->sa_family == AF_INET6)) { 890 if (!IN6_IS_ADDR_LINKLOCAL( 891 &satosin6(ifa->ifa_addr)->sin6_addr)) { 892 /* Done if we're looking for an IPv6 address */ 893 if (af == AF_INET6) 894 goto found; 895 /* Stick to the first one */ 896 if (ifa6 == NULL) 897 ifa6 = ifa; 898 } else /* Pick the last one */ 899 ifa6ll = ifa; 900 } 901 } 902 /* If we haven't found any IPv4 or IPv6 direct matches... */ 903 if (ifa == NULL) { 904 /* ... try the last global IPv6 address... */ 905 if (ifa6 != NULL) 906 ifa = ifa6; 907 /* ... or the last link-local... */ 908 else if (ifa6ll != NULL) 909 ifa = ifa6ll; 910 else { 911 splx(s); 912 KERNEL_UNLOCK(); 913 return (-1); 914 } 915 } 916 found: 917 switch (af) { 918 case AF_INET: 919 sin = satosin(ifa->ifa_addr); 920 inet_ntop(AF_INET, &sin->sin_addr, ipaddr, sizeof(ipaddr)); 921 copyout_utf16le(addr, ipaddr, addrlen, INET_ADDRSTRLEN); 922 923 sin = satosin(ifa->ifa_netmask); 924 inet_ntop(AF_INET, &sin->sin_addr, ipaddr, sizeof(ipaddr)); 925 copyout_utf16le(netmask, ipaddr, addrlen, INET_ADDRSTRLEN); 926 927 *family = ADDR_FAMILY_IPV4; 928 break; 929 case AF_UNSPEC: 930 case AF_INET6: 931 sin6 = satosin6(ifa->ifa_addr); 932 if (IN6_IS_SCOPE_EMBED(&sin6->sin6_addr)) { 933 sa6 = *satosin6(ifa->ifa_addr); 934 sa6.sin6_addr.s6_addr16[1] = 0; 935 sin6 = &sa6; 936 } 937 inet_ntop(AF_INET6, &sin6->sin6_addr, ipaddr, sizeof(ipaddr)); 938 copyout_utf16le(addr, ipaddr, addrlen, INET6_ADDRSTRLEN); 939 940 sin6 = satosin6(ifa->ifa_netmask); 941 inet_ntop(AF_INET6, &sin6->sin6_addr, ipaddr, sizeof(ipaddr)); 942 copyout_utf16le(netmask, ipaddr, addrlen, INET6_ADDRSTRLEN); 943 944 *family = ADDR_FAMILY_IPV6; 945 break; 946 } 947 948 splx(s); 949 KERNEL_UNLOCK(); 950 951 return (0); 952 } 953 954 static void 955 hv_kvp_process(struct hv_kvp *kvp, struct vmbus_icmsg_kvp *msg) 956 { 957 union hv_kvp_hdr *kvh = &msg->ic_kvh; 958 union hv_kvp_msg *kvm = &msg->ic_kvm; 959 960 switch (kvh->kvh_op) { 961 case HV_KVP_OP_SET: 962 if (kvh->kvh_pool == HV_KVP_POOL_AUTO_EXTERNAL && 963 kvp_pool_import(&kvp->kvp_pool[HV_KVP_POOL_AUTO_EXTERNAL], 964 kvm->kvm_val.kvm_key, kvm->kvm_val.kvm_keylen, 965 kvm->kvm_val.kvm_val, kvm->kvm_val.kvm_vallen, 966 kvm->kvm_val.kvm_valtype)) { 967 DPRINTF("%s: failed to import into 'Guest/Parameters'" 968 " pool\n", __func__); 969 kvh->kvh_err = HV_KVP_S_CONT; 970 } else if (kvh->kvh_pool == HV_KVP_POOL_EXTERNAL && 971 kvp_pool_import(&kvp->kvp_pool[HV_KVP_POOL_EXTERNAL], 972 kvm->kvm_val.kvm_key, kvm->kvm_val.kvm_keylen, 973 kvm->kvm_val.kvm_val, kvm->kvm_val.kvm_vallen, 974 kvm->kvm_val.kvm_valtype)) { 975 DPRINTF("%s: failed to import into 'External' pool\n", 976 __func__); 977 kvh->kvh_err = HV_KVP_S_CONT; 978 } else if (kvh->kvh_pool != HV_KVP_POOL_AUTO_EXTERNAL && 979 kvh->kvh_pool != HV_KVP_POOL_EXTERNAL) { 980 kvh->kvh_err = HV_KVP_S_CONT; 981 } else 982 kvh->kvh_err = HV_KVP_S_OK; 983 break; 984 case HV_KVP_OP_DELETE: 985 if (kvh->kvh_pool != HV_KVP_POOL_EXTERNAL || 986 kvp_pool_remove(&kvp->kvp_pool[HV_KVP_POOL_EXTERNAL], 987 kvm->kvm_del.kvm_key, kvm->kvm_del.kvm_keylen)) { 988 DPRINTF("%s: failed to remove from 'External' pool\n", 989 __func__); 990 kvh->kvh_err = HV_KVP_S_CONT; 991 } else 992 kvh->kvh_err = HV_KVP_S_OK; 993 break; 994 case HV_KVP_OP_ENUMERATE: 995 if (kvh->kvh_pool == HV_KVP_POOL_AUTO && 996 kvp_pool_export(&kvp->kvp_pool[HV_KVP_POOL_AUTO], 997 kvm->kvm_enum.kvm_index, kvm->kvm_enum.kvm_key, 998 &kvm->kvm_enum.kvm_keylen, kvm->kvm_enum.kvm_val, 999 &kvm->kvm_enum.kvm_vallen, &kvm->kvm_enum.kvm_valtype)) 1000 kvh->kvh_err = HV_KVP_S_CONT; 1001 else if (kvh->kvh_pool == HV_KVP_POOL_GUEST && 1002 kvp_pool_export(&kvp->kvp_pool[HV_KVP_POOL_GUEST], 1003 kvm->kvm_enum.kvm_index, kvm->kvm_enum.kvm_key, 1004 &kvm->kvm_enum.kvm_keylen, kvm->kvm_enum.kvm_val, 1005 &kvm->kvm_enum.kvm_vallen, &kvm->kvm_enum.kvm_valtype)) 1006 kvh->kvh_err = HV_KVP_S_CONT; 1007 else 1008 kvh->kvh_err = HV_KVP_S_OK; 1009 break; 1010 case HV_KVP_OP_GET_IP_INFO: 1011 if (VMBUS_ICVER_MAJOR(msg->ic_hdr.ic_msgver) <= 4) { 1012 struct vmbus_icmsg_kvp_addr *amsg; 1013 struct hv_kvp_msg_addr *kva; 1014 1015 amsg = (struct vmbus_icmsg_kvp_addr *)msg; 1016 kva = &amsg->ic_kvm; 1017 1018 if (kvp_get_ip_info(kvp, kva->kvm_mac, 1019 &kva->kvm_family, kva->kvm_addr, 1020 kva->kvm_netmask, sizeof(kva->kvm_addr))) 1021 kvh->kvh_err = HV_KVP_S_CONT; 1022 else 1023 kvh->kvh_err = HV_KVP_S_OK; 1024 } else { 1025 DPRINTF("KVP GET_IP_INFO fw %u.%u msg %u.%u dsize=%u\n", 1026 VMBUS_ICVER_MAJOR(msg->ic_hdr.ic_fwver), 1027 VMBUS_ICVER_MINOR(msg->ic_hdr.ic_fwver), 1028 VMBUS_ICVER_MAJOR(msg->ic_hdr.ic_msgver), 1029 VMBUS_ICVER_MINOR(msg->ic_hdr.ic_msgver), 1030 msg->ic_hdr.ic_dsize); 1031 kvh->kvh_err = HV_KVP_S_CONT; 1032 } 1033 break; 1034 default: 1035 DPRINTF("KVP message op %u pool %u\n", kvh->kvh_op, 1036 kvh->kvh_pool); 1037 kvh->kvh_err = HV_KVP_S_CONT; 1038 } 1039 } 1040 1041 void 1042 hv_kvp(void *arg) 1043 { 1044 struct hv_ic_dev *dv = arg; 1045 struct hv_channel *ch = dv->dv_ch; 1046 struct hv_softc *sc = ch->ch_sc; 1047 struct hv_kvp *kvp = dv->dv_priv; 1048 struct vmbus_icmsg_hdr *hdr; 1049 uint64_t rid; 1050 uint32_t fwver, msgver, rlen; 1051 int rv; 1052 1053 for (;;) { 1054 rv = hv_channel_recv(ch, dv->dv_buf, 2 * PAGE_SIZE, 1055 &rlen, &rid, 0); 1056 if (rv || rlen == 0) { 1057 if (rv != EAGAIN) 1058 DPRINTF("%s: kvp rv=%d rlen=%u\n", 1059 sc->sc_dev.dv_xname, rv, rlen); 1060 return; 1061 } 1062 if (rlen < sizeof(struct vmbus_icmsg_hdr)) { 1063 DPRINTF("%s: kvp short read rlen=%u\n", 1064 sc->sc_dev.dv_xname, rlen); 1065 return; 1066 } 1067 hdr = (struct vmbus_icmsg_hdr *)dv->dv_buf; 1068 switch (hdr->ic_type) { 1069 case VMBUS_ICMSG_TYPE_NEGOTIATE: 1070 switch (sc->sc_proto) { 1071 case VMBUS_VERSION_WS2008: 1072 fwver = VMBUS_IC_VERSION(1, 0); 1073 msgver = VMBUS_IC_VERSION(1, 0); 1074 break; 1075 case VMBUS_VERSION_WIN7: 1076 fwver = VMBUS_IC_VERSION(3, 0); 1077 msgver = VMBUS_IC_VERSION(3, 0); 1078 break; 1079 default: 1080 fwver = VMBUS_IC_VERSION(3, 0); 1081 msgver = VMBUS_IC_VERSION(4, 0); 1082 } 1083 hv_ic_negotiate(hdr, &rlen, fwver, msgver); 1084 break; 1085 case VMBUS_ICMSG_TYPE_KVP: 1086 if (hdr->ic_dsize >= sizeof(union hv_kvp_hdr)) 1087 hv_kvp_process(kvp, 1088 (struct vmbus_icmsg_kvp *)hdr); 1089 else 1090 printf("%s: message too short: %u\n", 1091 sc->sc_dev.dv_xname, hdr->ic_dsize); 1092 break; 1093 default: 1094 printf("%s: unhandled kvp message type %u\n", 1095 sc->sc_dev.dv_xname, hdr->ic_type); 1096 continue; 1097 } 1098 hdr->ic_flags = VMBUS_ICMSG_FLAG_TRANSACTION | 1099 VMBUS_ICMSG_FLAG_RESPONSE; 1100 hv_channel_send(ch, dv->dv_buf, rlen, rid, 1101 VMBUS_CHANPKT_TYPE_INBAND, 0); 1102 } 1103 } 1104 1105 static int 1106 kvp_poolname(char **key) 1107 { 1108 char *p; 1109 int i, rv = -1; 1110 1111 if ((p = strrchr(*key, '/')) == NULL) 1112 return (rv); 1113 *p = '\0'; 1114 for (i = 0; i < nitems(kvp_pools); i++) { 1115 if (strncasecmp(*key, kvp_pools[i].poolname, 1116 kvp_pools[i].poolnamelen) == 0) { 1117 rv = kvp_pools[i].poolidx; 1118 break; 1119 } 1120 } 1121 if (rv >= 0) 1122 *key = ++p; 1123 return (rv); 1124 } 1125 1126 int 1127 hv_kvop(void *arg, int op, char *key, char *val, size_t vallen) 1128 { 1129 struct hv_ic_dev *dv = arg; 1130 struct hv_kvp *kvp = dv->dv_priv; 1131 struct kvp_pool *kvpl; 1132 int next, pool, error = 0; 1133 char *vp = val; 1134 size_t keylen; 1135 1136 pool = kvp_poolname(&key); 1137 if (pool == -1) 1138 return (EINVAL); 1139 1140 kvpl = &kvp->kvp_pool[pool]; 1141 if (strlen(key) == 0) { 1142 for (next = 0; next < MAXPOOLENTS; next++) { 1143 if (val + vallen < vp + HV_KVP_MAX_KEY_SIZE / 2) 1144 return (ERANGE); 1145 if (kvp_pool_keys(kvpl, next, vp, &keylen)) 1146 goto out; 1147 if (strlcat(val, "\n", vallen) >= vallen) 1148 return (ERANGE); 1149 vp += keylen; 1150 } 1151 out: 1152 if (vp > val) 1153 *(vp - 1) = '\0'; 1154 return (0); 1155 } 1156 1157 if (op == PVBUS_KVWRITE) { 1158 if (pool == HV_KVP_POOL_AUTO) 1159 error = kvp_pool_update(kvpl, key, val, vallen, 1160 HV_KVP_REG_SZ); 1161 else if (pool == HV_KVP_POOL_GUEST) 1162 error = kvp_pool_insert(kvpl, key, val, vallen, 1163 HV_KVP_REG_SZ); 1164 else 1165 error = EINVAL; 1166 } else 1167 error = kvp_pool_extract(kvpl, key, val, vallen); 1168 1169 return (error); 1170 } 1171