VirtualBox

Changeset 58248 in vbox for trunk/src


Ignore:
Timestamp:
Oct 14, 2015 3:19:54 PM (9 years ago)
Author:
vboxsync
Message:

VMM/GIM: Implemented Hyper-V synthetic debug MSRs support. Added CFGM validation for GIM and Hyper-V.

Location:
trunk/src/VBox/VMM
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/GIMAllHv.cpp

    r58123 r58248  
    172172                        && rcHv == GIM_HV_STATUS_SUCCESS)
    173173                    {
    174                         LogRelMax(1, ("GIM: HyperV: Guest initiated debug data reception\n"));
     174                        LogRelMax(1, ("GIM: HyperV: Guest initiated debug data reception via hypercall\n"));
    175175                        rc = gimR3HvHypercallRetrieveDebugData(pVM, GCPhysOut, &rcHv);
    176176                        if (RT_FAILURE(rc))
     
    192192                        && rcHv == GIM_HV_STATUS_SUCCESS)
    193193                    {
    194                         LogRelMax(1, ("GIM: HyperV: Guest initiated debug data transmission\n"));
     194                        LogRelMax(1, ("GIM: HyperV: Guest initiated debug data transmission via hypercall\n"));
    195195                        rc = gimR3HvHypercallPostDebugData(pVM, GCPhysOut, &rcHv);
    196196                        if (RT_FAILURE(rc))
     
    234234                            rcHv = GIM_HV_STATUS_INVALID_PARAMETER;
    235235                        else
    236                             LogRelMax(1, ("GIM: HyperV: Guest resetting debug session\n"));
     236                            LogRelMax(1, ("GIM: HyperV: Guest resetting debug session via hypercall\n"));
    237237                    }
    238238                }
     
    396396                return VERR_CPUM_RAISE_GP_0;
    397397            return VINF_SUCCESS;
     398        }
     399
     400        case MSR_GIM_HV_SYNTH_DEBUG_STATUS:
     401            *puValue = pHv->uDebugStatusMsr;
     402            return VINF_SUCCESS;
     403
     404        case MSR_GIM_HV_SINT2:
     405        {
     406#ifndef IN_RING3
     407            return VINF_CPUM_R3_MSR_READ;
     408#else
     409            LogRelMax(10, ("GIM: HyperV: reading MSR_GIM_HV_SINT2 CS:RIP=%04x:%RX64\n", CPUMGetGuestCS(pVCpu), CPUMGetGuestRIP(pVCpu)));
     410            *puValue = RT_BIT_64(16);
     411            return VERR_CPUM_RAISE_GP_0;
     412#endif
     413        }
     414
     415        case MSR_GIM_HV_SIMP:
     416        {
     417#ifndef IN_RING3
     418            return VINF_CPUM_R3_MSR_READ;
     419#else
     420            LogRelMax(10, ("GIM: HyperV: reading MSR_GIM_HV_SIMP CS:RIP=%04x:%RX64\n", CPUMGetGuestCS(pVCpu), CPUMGetGuestRIP(pVCpu)));
     421            *puValue = 0;
     422            return VINF_SUCCESS;
     423#endif
    398424        }
    399425
     
    640666        }
    641667
     668        case MSR_GIM_HV_SYNTH_DEBUG_SEND_BUFFER:
     669        {
     670#ifndef IN_RING3
     671            return VINF_CPUM_R3_MSR_WRITE;
     672#else
     673            RTGCPHYS GCPhysBuffer    = (RTGCPHYS)uRawValue;
     674            pHv->uDebugSendBufferMsr = GCPhysBuffer;
     675            if (PGMPhysIsGCPhysNormal(pVM, GCPhysBuffer))
     676                LogRel(("GIM: HyperV: Guest set up debug send buffer at %#RGp\n", GCPhysBuffer));
     677            else
     678                LogRel(("GIM: HyperV: Guest destroyed debug send buffer\n"));
     679            pHv->uDebugSendBufferMsr = uRawValue;
     680            return VINF_SUCCESS;
     681#endif
     682        }
     683
     684        case MSR_GIM_HV_SYNTH_DEBUG_RECEIVE_BUFFER:
     685        {
     686#ifndef IN_RING3
     687            return VINF_CPUM_R3_MSR_WRITE;
     688#else
     689            RTGCPHYS GCPhysBuffer    = (RTGCPHYS)uRawValue;
     690            pHv->uDebugRecvBufferMsr = GCPhysBuffer;
     691            if (PGMPhysIsGCPhysNormal(pVM, GCPhysBuffer))
     692                LogRel(("GIM: HyperV: Guest set up debug receive buffer at %#RGp\n", GCPhysBuffer));
     693            else
     694                LogRel(("GIM: HyperV: Guest destroyed debug receive buffer\n"));
     695            return VINF_SUCCESS;
     696#endif
     697        }
     698
     699        case MSR_GIM_HV_SYNTH_DEBUG_PENDING_BUFFER:
     700        {
     701#ifndef IN_RING3
     702            return VINF_CPUM_R3_MSR_WRITE;
     703#else
     704            RTGCPHYS GCPhysBuffer        = (RTGCPHYS)uRawValue;
     705            pHv->uDebugPendingBufferMsr  = GCPhysBuffer;
     706            if (PGMPhysIsGCPhysNormal(pVM, GCPhysBuffer))
     707            {
     708                LogRel(("GIM: HyperV: Guest set up debug pending buffer at %#RGp\n", uRawValue));
     709
     710                /* Indicate that there is always debug data to be read (guest will poll). */
     711                uint8_t uPendingData = 1;
     712                int rc = PGMPhysSimpleWriteGCPhys(pVM, GCPhysBuffer, (void *)&uPendingData, sizeof(uPendingData));
     713                if (RT_FAILURE(rc))
     714                    LogRelMax(5, ("GIM: HyperV: Failed to update pending buffer at %#RGp, rc=%Rrc\n", GCPhysBuffer, rc));
     715            }
     716            else
     717                LogRel(("GIM: HyperV: Guest destroyed debug pending buffer\n"));
     718            return VINF_SUCCESS;
     719#endif
     720        }
     721
     722        case MSR_GIM_HV_SYNTH_DEBUG_CONTROL:
     723        {
     724#ifndef IN_RING3
     725            return VINF_CPUM_R3_MSR_WRITE;
     726#else
     727            if (MSR_GIM_HV_SYNTH_DEBUG_CONTROL_IS_WRITE(uRawValue))
     728            {
     729                LogRelMax(1, ("GIM: HyperV: Guest initiated debug data transmission via MSR\n",
     730                              MSR_GIM_HV_SYNTH_DEBUG_CONTROL_W_LEN(uRawValue)));
     731                size_t cbWrite = MSR_GIM_HV_SYNTH_DEBUG_CONTROL_W_LEN(uRawValue);
     732                if (   cbWrite > 0
     733                    && cbWrite < GIM_HV_PAGE_SIZE)
     734                {
     735                    void *pvBuf = RTMemAlloc(cbWrite);  /** @todo perhaps we can do this alloc once during VM init. */
     736                    if (RT_LIKELY(pvBuf))
     737                    {
     738                        if (PGMPhysIsGCPhysNormal(pVM, (RTGCPHYS)pHv->uDebugSendBufferMsr))
     739                        {
     740                            int rc = PGMPhysSimpleReadGCPhys(pVM, pvBuf, (RTGCPHYS)pHv->uDebugSendBufferMsr, cbWrite);
     741                            if (RT_SUCCESS(rc))
     742                            {
     743                                uint32_t cbWritten = 0;
     744                                rc = gimR3HvDebugWrite(pVM, pvBuf, cbWrite, &cbWritten, false /*fUdpPkt*/);
     745                                if (   RT_SUCCESS(rc)
     746                                    && cbWrite == cbWritten)
     747                                    pHv->uDebugStatusMsr = MSR_GIM_HV_SYNTH_DEBUG_STATUS_W_SUCCESS_BIT;
     748                                else
     749                                    pHv->uDebugStatusMsr = 0;
     750                            }
     751                            else
     752                            {
     753                                LogRelMax(5, ("GIM: HyperV: Failed to read debug send buffer at %#RGp, rc=%Rrc\n",
     754                                              (RTGCPHYS)pHv->uDebugSendBufferMsr, rc));
     755                            }
     756                        }
     757                        else
     758                            LogRelMax(5, ("GIM: HyperV: Debug send buffer address %#RGp invalid! Ignoring debug write\n",
     759                                          (RTGCPHYS)pHv->uDebugSendBufferMsr));
     760                        RTMemFree(pvBuf);
     761                    }
     762                    else
     763                    {
     764                        LogRel(("GIM: HyperV: Failed to alloc %u bytes for copying debug send buffer\n", cbWrite));
     765                        return VERR_NO_MEMORY;
     766                    }
     767                }
     768            }
     769            else if (MSR_GIM_HV_SYNTH_DEBUG_CONTROL_IS_READ(uRawValue))
     770            {
     771                LogRelMax(1, ("GIM: HyperV: Guest initiated debug data reception via MSR\n"));
     772                if (PGMPhysIsGCPhysNormal(pVM, (RTGCPHYS)pHv->uDebugRecvBufferMsr))
     773                {
     774                    void *pvBuf = RTMemAlloc(PAGE_SIZE);        /** @todo perhaps we can do this alloc once during VM init. */
     775                    if (RT_LIKELY(pvBuf))
     776                    {
     777                        uint32_t cbReallyRead;
     778                        int rc = gimR3HvDebugRead(pVM, pvBuf, PAGE_SIZE, PAGE_SIZE, &cbReallyRead, 0, false /*fUdpPkt*/);
     779                        if (   RT_SUCCESS(rc)
     780                            && cbReallyRead > 0)
     781                        {
     782                            rc = PGMPhysSimpleWriteGCPhys(pVM, (RTGCPHYS)pHv->uDebugRecvBufferMsr, pvBuf, cbReallyRead);
     783                            if (RT_SUCCESS(rc))
     784                            {
     785                                pHv->uDebugStatusMsr  = ((uint16_t)cbReallyRead) << 16;
     786                                pHv->uDebugStatusMsr |= MSR_GIM_HV_SYNTH_DEBUG_STATUS_R_SUCCESS_BIT;
     787                            }
     788                            else
     789                            {
     790                                pHv->uDebugStatusMsr = 0;
     791                                LogRelMax(5, ("GIM: HyperV: PGMPhysSimpleWriteGCPhys failed. rc=%Rrc\n", rc));
     792                            }
     793                        }
     794                        else
     795                            pHv->uDebugStatusMsr = 0;
     796                        RTMemFree(pvBuf);
     797                    }
     798                    else
     799                    {
     800                        LogRel(("GIM: HyperV: Failed to alloc %u bytes for copying debug receive buffer\n", PAGE_SIZE));
     801                        return VERR_NO_MEMORY;
     802                    }
     803                }
     804                else
     805                    LogRelMax(5, ("GIM: HyperV: Debug receive buffer address %#RGp invalid! Ignoring debug data reception\n"));
     806            }
     807            return VINF_SUCCESS;
     808#endif
     809        }
     810
     811        case MSR_GIM_HV_SINT2:
     812#ifndef IN_RING3
     813            return VINF_CPUM_R3_MSR_WRITE;
     814#else
     815            LogRelMax(5, ("GIM: HyperV: Guest writing MSR_GIM_HV_SINT2 with %#RX64, ignoring CS:RIP=%04x:%RX64\n", uRawValue,
     816                           CPUMGetGuestCS(pVCpu), CPUMGetGuestRIP(pVCpu)));
     817            return VERR_CPUM_RAISE_GP_0;
     818#endif
     819
    642820        case MSR_GIM_HV_CRASH_P0:  pHv->uCrashP0 = uRawValue;  return VINF_SUCCESS;
    643821        case MSR_GIM_HV_CRASH_P1:  pHv->uCrashP1 = uRawValue;  return VINF_SUCCESS;
     
    660838                return VINF_CPUM_R3_MSR_WRITE;
    661839#else
    662                 LogRelMax(1, ("GIM: HyperV: Guest setting debug options MSR to %#RX64, ignoring\n", uRawValue));
     840                LogRelMax(5, ("GIM: HyperV: Guest setting debug options MSR to %#RX64, ignoring\n", uRawValue));
    663841                return VINF_SUCCESS;
    664842#endif
  • trunk/src/VBox/VMM/VMMR3/GIM.cpp

    r58126 r58248  
    110110    PCFGMNODE pCfgNode = CFGMR3GetChild(CFGMR3GetRoot(pVM), "GIM/");
    111111
     112    /*
     113     * Validate the GIM settings.
     114     */
     115    rc = CFGMR3ValidateConfig(pCfgNode, "/GIM/",
     116                              "Provider"   /* pszValidValues */
     117                              "|Version",
     118                              "HyperV"     /* pszValidNodes */,
     119                              "GIM"        /* pszWho */,
     120                              0            /* uInstance */);
     121    if (RT_FAILURE(rc))
     122        return rc;
     123
    112124    /** @cfgm{/GIM/Provider, string}
    113125     * The name of the GIM provider. The default is "none". */
     
    143155        {
    144156            pVM->gim.s.enmProviderId = GIMPROVIDERID_HYPERV;
    145             rc = gimR3HvInit(pVM);
     157            rc = gimR3HvInit(pVM, pCfgNode);
    146158        }
    147159        else if (!RTStrCmp(szProvider, "KVM"))
  • trunk/src/VBox/VMM/VMMR3/GIMHv.cpp

    r58126 r58248  
    8484*   Internal Functions                                                                                                           *
    8585*********************************************************************************************************************************/
    86 static int    gimR3HvInitDebugSupport(PVM pVM);
    87 static void   gimR3HvTermDebugSupport(PVM pVM);
     86static int    gimR3HvInitHypercallSupport(PVM pVM);
     87static void   gimR3HvTermHypercallSupport(PVM pVM);
    8888
    8989
     
    9494 * @param   pVM         The cross context VM structure.
    9595 */
    96 VMMR3_INT_DECL(int) gimR3HvInit(PVM pVM)
     96VMMR3_INT_DECL(int) gimR3HvInit(PVM pVM, PCFGMNODE pGimCfg)
    9797{
    9898    AssertReturn(pVM, VERR_INVALID_PARAMETER);
     
    105105     * Read configuration.
    106106     */
    107     PCFGMNODE pCfgNode = CFGMR3GetChild(CFGMR3GetRoot(pVM), "GIM/HyperV");
     107    PCFGMNODE pCfgHv = CFGMR3GetChild(pGimCfg, "HyperV");
     108    if (pCfgHv)
     109    {
     110        /*
     111         * Validate the Hyper-V settings.
     112         */
     113        rc = CFGMR3ValidateConfig(pCfgHv, "/HyperV/",
     114                                  "VendorID",
     115                                  "" /* pszValidNodes */, "GIM/HyperV" /* pszWho */, 0 /* uInstance */);
     116        if (RT_FAILURE(rc))
     117            return rc;
     118    }
    108119
    109120    /** @cfgm{/GIM/HyperV/VendorID, string, 'VBoxVBoxVBox'}
    110121     * The Hyper-V vendor signature, must be 12 characters. */
    111122    char szVendor[13];
    112     rc = CFGMR3QueryStringDef(pCfgNode, "VendorID", szVendor, sizeof(szVendor), "VBoxVBoxVBox");
     123    rc = CFGMR3QueryStringDef(pCfgHv, "VendorID", szVendor, sizeof(szVendor), "VBoxVBoxVBox");
    113124    AssertLogRelRCReturn(rc, rc);
    114125
     
    119130        pHv->fIsVendorMsHv = true;
    120131    }
     132
     133    pHv->fIsInterfaceVs = true;
    121134
    122135    /*
     
    156169
    157170        /* Expose more if we're posing as Microsoft. */
    158         if (pHv->fIsVendorMsHv)
     171        if (   pHv->fIsVendorMsHv
     172            /*&& !pHv->fIsInterfaceVs*/)
    159173        {
    160174            pHv->uMiscFeat  |= GIM_HV_MISC_FEAT_GUEST_DEBUGGING
     
    274288    AssertLogRelRCReturn(rc, rc);
    275289
     290    if (   pHv->fIsVendorMsHv
     291        && pHv->fIsInterfaceVs)
     292    {
     293        HyperLeaf.uLeaf        = UINT32_C(0x40000080);
     294        HyperLeaf.uEax         = 0;
     295        HyperLeaf.uEbx         = 0x7263694d;        /* 'rciM' */
     296        HyperLeaf.uEcx         = 0x666f736f;        /* 'foso'*/
     297        HyperLeaf.uEdx         = 0x53562074;        /* 'SV t' */
     298        rc = CPUMR3CpuIdInsert(pVM, &HyperLeaf);
     299        AssertLogRelRCReturn(rc, rc);
     300
     301        HyperLeaf.uLeaf        = UINT32_C(0x40000081);
     302        HyperLeaf.uEax         = 0x31235356;        /* '1#SV' */
     303        HyperLeaf.uEbx         = 0;
     304        HyperLeaf.uEcx         = 0;
     305        HyperLeaf.uEdx         = 0;
     306        rc = CPUMR3CpuIdInsert(pVM, &HyperLeaf);
     307        AssertLogRelRCReturn(rc, rc);
     308
     309        HyperLeaf.uLeaf        = UINT32_C(0x40000082);
     310        HyperLeaf.uEax         = RT_BIT_32(1);
     311        HyperLeaf.uEbx         = 0;
     312        HyperLeaf.uEcx         = 0;
     313        HyperLeaf.uEdx         = 0;
     314        rc = CPUMR3CpuIdInsert(pVM, &HyperLeaf);
     315        AssertLogRelRCReturn(rc, rc);
     316    }
     317
    276318    /*
    277319     * Insert all MSR ranges of Hyper-V.
     
    290332
    291333    /*
    292      * Setup guest-host debugging connection.
     334     * Setup guest-host hypercall based debugging support.
    293335     */
    294336    if (pHv->uMiscFeat & GIM_HV_MISC_FEAT_GUEST_DEBUGGING)
    295337    {
    296         rc = gimR3HvInitDebugSupport(pVM);
     338        rc = gimR3HvInitHypercallSupport(pVM);
    297339        AssertLogRelRCReturn(rc, rc);
    298340    }
     
    366408    PGIMHV pHv = &pVM->gim.s.u.Hv;
    367409    if (pHv->uMiscFeat & GIM_HV_MISC_FEAT_GUEST_DEBUGGING)
    368         gimR3HvTermDebugSupport(pVM);
     410        gimR3HvTermHypercallSupport(pVM);
    369411    return VINF_SUCCESS;
    370412}
     
    422464     * Reset MSRs (Careful! Don't reset non-zero MSRs).
    423465     */
    424     pHv->u64GuestOsIdMsr = 0;
    425     pHv->u64HypercallMsr = 0;
    426     pHv->u64TscPageMsr   = 0;
    427     pHv->uCrashP0        = 0;
    428     pHv->uCrashP1        = 0;
    429     pHv->uCrashP2        = 0;
    430     pHv->uCrashP3        = 0;
    431     pHv->uCrashP4        = 0;
     466    pHv->u64GuestOsIdMsr        = 0;
     467    pHv->u64HypercallMsr        = 0;
     468    pHv->u64TscPageMsr          = 0;
     469    pHv->uCrashP0               = 0;
     470    pHv->uCrashP1               = 0;
     471    pHv->uCrashP2               = 0;
     472    pHv->uCrashP3               = 0;
     473    pHv->uCrashP4               = 0;
     474    pHv->uDebugStatusMsr        = 0;
     475    pHv->uDebugPendingBufferMsr = 0;
     476    pHv->uDebugSendBufferMsr    = 0;
     477    pHv->uDebugRecvBufferMsr    = 0;
    432478}
    433479
     
    909955
    910956/**
    911  * Initializes Hyper-V guest debugging support.
     957 * Initializes Hyper-V guest hypercall support.
    912958 *
    913959 * @returns VBox status code.
    914960 * @param   pVM     The cross context VM structure.
    915961 */
    916 static int gimR3HvInitDebugSupport(PVM pVM)
     962static int gimR3HvInitHypercallSupport(PVM pVM)
    917963{
    918964    int rc = VINF_SUCCESS;
     
    931977
    932978/**
    933  * Terminates Hyper-V guest debugging support.
     979 * Terminates Hyper-V guest hypercall support.
    934980 *
    935981 * @param   pVM     The cross context VM structure.
    936982 */
    937 static void gimR3HvTermDebugSupport(PVM pVM)
     983static void gimR3HvTermHypercallSupport(PVM pVM)
    938984{
    939985    PGIMHV pHv = &pVM->gim.s.u.Hv;
     
    952998 * @param   pVM         The cross context VM structure.
    953999 * @param   pvBuf       Where to read the data.
    954  * @param   cbBuf       Size of the read buffer @a pvBuf.
     1000 * @param   cbBuf       Size of the read buffer @a pvBuf, must be >= @a cbRead.
     1001 * @param   cbRead      Number of bytes to read.
    9551002 * @param   pcbRead     Where to store how many bytes were really read.
    9561003 * @param   cMsTimeout  Timeout of the read operation in milliseconds.
     1004 * @param   fUdpPkt     Whether the debug data returned in @a pvBuf needs to be
     1005 *                      encapsulated in a UDP frame.
    9571006 *
    9581007 * @thread  EMT.
    9591008 */
    960 static int gimR3HvDebugRead(PVM pVM, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead, uint32_t cMsTimeout)
    961 {
    962     NOREF(cMsTimeout);      /** @todo implement */
    963     PGIMHV pHv = &pVM->gim.s.u.Hv;
     1009VMMR3_INT_DECL(int) gimR3HvDebugRead(PVM pVM, void *pvBuf, uint32_t cbBuf, uint32_t cbRead, uint32_t *pcbRead,
     1010                                     uint32_t cMsTimeout, bool fUdpPkt)
     1011{
     1012    NOREF(cMsTimeout);      /** @todo implement timeout. */
    9641013    AssertCompile(sizeof(size_t) >= sizeof(uint32_t));
    965     size_t cbRead = cbBuf;
    966     int rc = GIMR3DebugRead(pVM, pvBuf, &cbRead);
    967     *pcbRead = (uint32_t)cbRead;
     1014    AssertReturn(cbBuf >= cbRead, VERR_INVALID_PARAMETER);
     1015
     1016    /*
     1017     * Read the data.
     1018     */
     1019    size_t cbReallyRead = cbRead;
     1020    int rc = GIMR3DebugRead(pVM, pvBuf, &cbReallyRead);
     1021
     1022    /*
     1023     * Encapsulate it in a UDP packet if required.
     1024     */
     1025    if (   RT_SUCCESS(rc)
     1026        && fUdpPkt
     1027        && cbReallyRead > 0)
     1028    {
     1029        uint8_t abFrame[sizeof(RTNETETHERHDR) + RTNETIPV4_MIN_LEN + sizeof(RTNETUDP)];
     1030        if (cbReallyRead + sizeof(abFrame) <= cbBuf)
     1031        {
     1032            /*
     1033             * Windows guests pumps ethernet frames over the Hyper-V debug connection as
     1034             * explained in gimR3HvHypercallPostDebugData(). Here, we reconstruct the packet
     1035             * with the guest's self-chosen IP ARP address we saved in pHv->DbgGuestAddr.
     1036             *
     1037             * Note! We really need to pass the minimum IPv4 header length. The Windows 10 guest
     1038             * is -not- happy if we include the IPv4 options field, i.e. using sizeof(RTNETIPV4)
     1039             * instead of RTNETIPV4_MIN_LEN.
     1040             */
     1041            PGIMHV pHv = &pVM->gim.s.u.Hv;
     1042            RT_ZERO(abFrame);
     1043            PRTNETETHERHDR pEthHdr = (PRTNETETHERHDR)&abFrame[0];
     1044            PRTNETIPV4     pIpHdr  = (PRTNETIPV4)    (pEthHdr + 1);
     1045            PRTNETUDP      pUdpHdr = (PRTNETUDP)     ((uint8_t *)pIpHdr + RTNETIPV4_MIN_LEN);
     1046
     1047            /* Ethernet */
     1048            pEthHdr->EtherType = RT_H2N_U16_C(RTNET_ETHERTYPE_IPV4);
     1049            /* IPv4 */
     1050            pIpHdr->ip_v       = 4;
     1051            pIpHdr->ip_hl      = RTNETIPV4_MIN_LEN / sizeof(uint32_t);
     1052            pIpHdr->ip_tos     = 0;
     1053            pIpHdr->ip_len     = RT_H2N_U16((uint16_t)cbReallyRead + sizeof(RTNETUDP) + RTNETIPV4_MIN_LEN);
     1054            pIpHdr->ip_id      = 0;
     1055            pIpHdr->ip_off     = 0;
     1056            pIpHdr->ip_ttl     = 255;
     1057            pIpHdr->ip_p       = RTNETIPV4_PROT_UDP;
     1058            pIpHdr->ip_sum     = 0;
     1059            pIpHdr->ip_src.u   = 0;
     1060            pIpHdr->ip_dst.u   = pHv->DbgGuestAddr.u;
     1061            pIpHdr->ip_sum     = RTNetIPv4HdrChecksum(pIpHdr);
     1062            /* UDP */
     1063            pUdpHdr->uh_ulen   = RT_H2N_U16_C((uint16_t)cbReallyRead + sizeof(*pUdpHdr));
     1064
     1065            /* Make room by moving the payload and prepending the headers. */
     1066            uint8_t *pbData = (uint8_t *)pvBuf;
     1067            memmove(pbData + sizeof(abFrame), pbData, cbReallyRead);
     1068            memcpy(pbData, &abFrame[0], sizeof(abFrame));
     1069
     1070            /* Update the adjusted sizes. */
     1071            cbReallyRead += sizeof(abFrame);
     1072        }
     1073        else
     1074            rc = VERR_BUFFER_UNDERFLOW;
     1075    }
     1076
     1077    *pcbRead = (uint32_t)cbReallyRead;
    9681078    return rc;
    9691079}
     
    9751085 * @returns VBox status code.
    9761086 * @param   pVM         The cross context VM structure.
    977  * @param   pvBuf       Pointer to the data to be written.
    978  * @param   cbBuf       Size of the write buffer @a pvBuf.
    979  * @param   pcbWritten  Where to store how many bytes were really written.
     1087 * @param   pvData      Pointer to the data to be written.
     1088 * @param   cbWrite     Size of the write buffer @a pvData.
     1089 * @param   pcbWritten  Where to store the number of bytes written.
     1090 * @param   fUdpPkt     Whether the debug data in @a pvData is encapsulated in a
     1091 *                      UDP frame.
    9801092 *
    9811093 * @thread  EMT.
    9821094 */
    983 static int gimR3HvDebugWrite(PVM pVM, void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten)
    984 {
    985     PGIMHV pHv = &pVM->gim.s.u.Hv;
    986     AssertCompile(sizeof(size_t) >= sizeof(uint32_t));
    987     size_t cbWrite = cbBuf;
    988     int rc = GIMR3DebugWrite(pVM, pvBuf, &cbWrite);
    989     *pcbWritten = (uint32_t)cbWrite;
    990     return rc;
     1095VMMR3_INT_DECL(int) gimR3HvDebugWrite(PVM pVM, void *pvData, uint32_t cbWrite, uint32_t *pcbWritten, bool fUdpPkt)
     1096{
     1097    Assert(cbWrite > 0);
     1098
     1099    PGIMHV    pHv        = &pVM->gim.s.u.Hv;
     1100    bool      fIgnorePkt = false;
     1101    uint8_t  *pbData     = (uint8_t *)pvData;
     1102    if (fUdpPkt)
     1103    {
     1104        /*
     1105         * Windows guests sends us ethernet frames over the Hyper-V debug connection.
     1106         * It sends DHCP/ARP queries with zero'd out MAC addresses and requires fudging up the
     1107         * packets somewhere.
     1108         *
     1109         * The Microsoft WinDbg debugger talks UDP and thus only expects the actual debug
     1110         * protocol payload.
     1111         *
     1112         * At present, we only handle guests configured with the "nodhcp" option. This makes
     1113         * the guest send ARP queries with a self-chosen IP and after a couple of attempts of
     1114         * receiving no replies, the guest picks its own IP address. After this, the guest
     1115         * starts sending the UDP packets we require. We thus ignore the initial ARP packets
     1116         * (and to be safe all non-UDP packets) until the guest eventually starts talking
     1117         * UDP. Then we can finally feed the UDP payload over the debug connection.
     1118         */
     1119        if (cbWrite > sizeof(RTNETETHERHDR))
     1120        {
     1121            PCRTNETETHERHDR pEtherHdr = (PCRTNETETHERHDR)pbData;
     1122            if (pEtherHdr->EtherType == RT_H2N_U16_C(RTNET_ETHERTYPE_IPV4))
     1123            {
     1124                if (cbWrite > sizeof(RTNETETHERHDR) + RTNETIPV4_MIN_LEN + RTNETUDP_MIN_LEN)
     1125                {
     1126                    size_t const cbMaxIpHdr = cbWrite - sizeof(RTNETETHERHDR) - sizeof(RTNETUDP) - 1;
     1127                    size_t const cbMaxIpPkt = cbWrite - sizeof(RTNETETHERHDR);
     1128                    PCRTNETIPV4  pIp4Hdr    = (PCRTNETIPV4)(pbData + sizeof(RTNETETHERHDR));
     1129                    bool const   fValidIp4  = RTNetIPv4IsHdrValid(pIp4Hdr, cbMaxIpHdr, cbMaxIpPkt, false /*fChecksum*/);
     1130                    if (   fValidIp4
     1131                        && pIp4Hdr->ip_p == RTNETIPV4_PROT_UDP)
     1132                    {
     1133                        uint32_t const cbIpHdr     = pIp4Hdr->ip_hl * 4;
     1134                        uint32_t const cbMaxUdpPkt = cbWrite - sizeof(RTNETETHERHDR) - cbIpHdr;
     1135                        PCRTNETUDP pUdpHdr       = (PCRTNETUDP)((uint8_t *)pIp4Hdr + cbIpHdr);
     1136                        if (   pUdpHdr->uh_ulen >  RT_H2N_U16(sizeof(RTNETUDP))
     1137                            && pUdpHdr->uh_ulen <= RT_H2N_U16((uint16_t)cbMaxUdpPkt))
     1138                        {
     1139                            /*
     1140                             * Extract the UDP payload and pass it to the debugger and record the guest IP address.
     1141                             * Hyper-V sends UDP debugger packets with source and destination port as 0. If we don't
     1142                             * filter out the ports here, we would receive BOOTP, NETBIOS and other UDP sub-protocol
     1143                             * packets which the debugger yells as "Bad packet received from...".
     1144                             */
     1145                            if (   !pUdpHdr->uh_dport
     1146                                && !pUdpHdr->uh_sport)
     1147                            {
     1148                                uint32_t const cbFrameHdr = sizeof(RTNETETHERHDR) + cbIpHdr + sizeof(RTNETUDP);
     1149                                pbData  += cbFrameHdr;
     1150                                cbWrite -= cbFrameHdr;
     1151                                pHv->DbgGuestAddr = pIp4Hdr->ip_src;
     1152                            }
     1153                            else
     1154                            {
     1155                                LogFlow(("GIM: HyperV: Ignoring UDP packet not src and dst port 0\n"));
     1156                                fIgnorePkt = true;
     1157                            }
     1158                        }
     1159                        else
     1160                        {
     1161                            LogFlow(("GIM: HyperV: Ignoring malformed UDP packet. cbMaxUdpPkt=%u UdpPkt.len=%u\n", cbMaxUdpPkt,
     1162                                     RT_N2H_U16(pUdpHdr->uh_ulen)));
     1163                            fIgnorePkt = true;
     1164                        }
     1165                    }
     1166                    else
     1167                    {
     1168                        LogFlow(("GIM: HyperV: Ignoring non-IP / non-UDP packet. fValidIp4=%RTbool Proto=%u\n", fValidIp4,
     1169                                  pIp4Hdr->ip_p));
     1170                        fIgnorePkt = true;
     1171                    }
     1172                }
     1173                else
     1174                {
     1175                    LogFlow(("GIM: HyperV: Ignoring IPv4 packet; too short to be valid UDP. cbWrite=%u\n", cbWrite));
     1176                    fIgnorePkt = true;
     1177                }
     1178            }
     1179            else
     1180            {
     1181                LogFlow(("GIM: HyperV: Ignoring non-IP packet. Ethertype=%#x\n", RT_N2H_U16(pEtherHdr->EtherType)));
     1182                fIgnorePkt = true;
     1183            }
     1184        }
     1185    }
     1186
     1187    if (!fIgnorePkt)
     1188    {
     1189        AssertCompile(sizeof(size_t) >= sizeof(uint32_t));
     1190        size_t cbWriteBuf = cbWrite;
     1191        int rc = GIMR3DebugWrite(pVM, pbData, &cbWriteBuf);
     1192        if (   RT_SUCCESS(rc)
     1193            && cbWriteBuf == cbWrite)
     1194            *pcbWritten = (uint32_t)cbWriteBuf;
     1195        else
     1196            *pcbWritten = 0;
     1197    }
     1198    else
     1199        *pcbWritten = cbWrite;
     1200
     1201    return VINF_SUCCESS;
    9911202}
    9921203
     
    10201231
    10211232    PGIMHVDEBUGPOSTOUT pOut = (PGIMHVDEBUGPOSTOUT)pHv->pbHypercallOut;
    1022     AssertPtrReturn(pOut, VERR_GIM_IPE_2);
    1023     uint32_t *pcbPendingWrite = &pOut->cbPending;
    10241233
    10251234    /*
     
    10341243        rcHv = GIM_HV_STATUS_INVALID_PARAMETER;
    10351244    else if (!cbWrite)
     1245    {
    10361246        rcHv = GIM_HV_STATUS_SUCCESS;
     1247        pOut->cbPending = 0;
     1248    }
    10371249    else if (cbWrite > 0)
    10381250    {
    1039         bool fIgnorePacket = false;
    1040         if (pHv->fIsVendorMsHv)
     1251        uint32_t cbWritten = 0;
     1252        int rc2 = gimR3HvDebugWrite(pVM, pbData, cbWrite, &cbWritten, pHv->fIsVendorMsHv /*fUdpPkt*/);
     1253        if (   RT_SUCCESS(rc2)
     1254            && cbWritten == cbWrite)
    10411255        {
    1042             /*
    1043              * Windows guests sends us ethernet frames over the Hyper-V debug connection.
    1044              * It sends DHCP/ARP queries with zero'd out MAC addresses and requires fudging up the
    1045              * packets somewhere.
    1046              *
    1047              * The Microsoft WinDbg debugger talks UDP and thus only expects the actual debug
    1048              * protocol payload.
    1049              *
    1050              * At present, we only handle guests configured with the "nodhcp" option. This makes
    1051              * the guest send ARP queries with a self-chosen IP and after a couple of attempts of
    1052              * receiving no replies, the guest picks its own IP address. After this, the guest
    1053              * starts sending the UDP packets we require. We thus ignore the initial ARP packets
    1054              * (and to be safe all non-UDP packets) until the guest eventually starts talking
    1055              * UDP. Then we can finally feed the UDP payload over the debug connection.
    1056              */
    1057             if (cbWrite > sizeof(RTNETETHERHDR))
    1058             {
    1059                 PCRTNETETHERHDR pEtherHdr = (PCRTNETETHERHDR)pbData;
    1060                 if (pEtherHdr->EtherType == RT_H2N_U16_C(RTNET_ETHERTYPE_IPV4))
    1061                 {
    1062                     if (cbWrite > sizeof(RTNETETHERHDR) + RTNETIPV4_MIN_LEN + RTNETUDP_MIN_LEN)
    1063                     {
    1064                         size_t const cbMaxIpHdr = cbWrite - sizeof(RTNETETHERHDR) - sizeof(RTNETUDP) - 1;
    1065                         size_t const cbMaxIpPkt = cbWrite - sizeof(RTNETETHERHDR);
    1066                         PCRTNETIPV4  pIp4Hdr    = (PCRTNETIPV4)(pbData + sizeof(RTNETETHERHDR));
    1067                         bool const   fValidIp4  = RTNetIPv4IsHdrValid(pIp4Hdr, cbMaxIpHdr, cbMaxIpPkt, false /*fChecksum*/);
    1068                         if (   fValidIp4
    1069                             && pIp4Hdr->ip_p == RTNETIPV4_PROT_UDP)
    1070                         {
    1071                             uint32_t const cbIpHdr     = pIp4Hdr->ip_hl * 4;
    1072                             uint32_t const cbMaxUdpPkt = cbWrite - sizeof(RTNETETHERHDR) - cbIpHdr;
    1073                             PCRTNETUDP pUdpHdr       = (PCRTNETUDP)((uint8_t *)pIp4Hdr + cbIpHdr);
    1074                             if (   pUdpHdr->uh_ulen >  RT_H2N_U16(sizeof(RTNETUDP))
    1075                                 && pUdpHdr->uh_ulen <= RT_H2N_U16((uint16_t)cbMaxUdpPkt))
    1076                             {
    1077                                 /*
    1078                                  * Extract the UDP payload and pass it to the debugger and record the guest IP address.
    1079                                  * Hyper-V sends UDP debugger packets with source and destination port as 0. If we don't
    1080                                  * filter out the ports here, we would receive BOOTP, NETBIOS and other UDP sub-protocol
    1081                                  * packets which the debugger yells as "Bad packet received from...".
    1082                                  */
    1083                                 if (   !pUdpHdr->uh_dport
    1084                                     && !pUdpHdr->uh_sport)
    1085                                 {
    1086                                     uint32_t const cbFrameHdr = sizeof(RTNETETHERHDR) + cbIpHdr + sizeof(RTNETUDP);
    1087                                     pbData  += cbFrameHdr;
    1088                                     cbWrite -= cbFrameHdr;
    1089                                     pHv->DbgGuestAddr = pIp4Hdr->ip_src;
    1090                                 }
    1091                                 else
    1092                                 {
    1093                                     LogFlow(("GIM: HyperV: Ignoring UDP packet not src and dst port 0\n"));
    1094                                     fIgnorePacket = true;
    1095                                 }
    1096                             }
    1097                             else
    1098                             {
    1099                                 LogFlow(("GIM: HyperV: Ignoring malformed UDP packet. cbMaxUdpPkt=%u UdpPkt.len=%u\n",
    1100                                          cbMaxUdpPkt, RT_N2H_U16(pUdpHdr->uh_ulen)));
    1101                                 fIgnorePacket = true;
    1102                             }
    1103                         }
    1104                         else
    1105                         {
    1106                             LogFlow(("GIM: HyperV: Ignoring non-IP / non-UDP packet. fValidIp4=%RTBool Proto=%u\n", fValidIp4,
    1107                                       pIp4Hdr->ip_p));
    1108                             fIgnorePacket = true;
    1109                         }
    1110                     }
    1111                     else
    1112                     {
    1113                         LogFlow(("GIM: HyperV: Ignoring IPv4 packet; too short to be valid UDP. cbWrite=%u\n", cbWrite));
    1114                         fIgnorePacket = true;
    1115                     }
    1116                 }
    1117                 else
    1118                 {
    1119                     LogFlow(("GIM: HyperV: Ignoring non-IP packet. Ethertype=%#x\n", RT_N2H_U16(pEtherHdr->EtherType)));
    1120                     fIgnorePacket = true;
    1121                 }
    1122             }
    1123         }
    1124 
    1125         if (!fIgnorePacket)
    1126         {
    1127             uint32_t cbReallyWritten = 0;
    1128             int rc2 = gimR3HvDebugWrite(pVM, pbData, cbWrite, &cbReallyWritten);
    1129             if (   RT_SUCCESS(rc2)
    1130                 && cbReallyWritten == cbWrite)
    1131             {
    1132                 *pcbPendingWrite = 0;
    1133                 rcHv = GIM_HV_STATUS_SUCCESS;
    1134             }
    1135             else
    1136             {
    1137                 /*
    1138                  * No need to update "*pcbPendingWrite" here as the guest isn't supposed to/doesn't
    1139                  * look at any of the output parameters when we fail the hypercall operation.
    1140                  */
    1141                 rcHv = GIM_HV_STATUS_INSUFFICIENT_BUFFERS;
    1142             }
     1256            pOut->cbPending = 0;
     1257            rcHv = GIM_HV_STATUS_SUCCESS;
    11431258        }
    11441259        else
    1145         {
    1146             /* Pretend success. */
    1147             *pcbPendingWrite = 0;
    1148             rcHv = GIM_HV_STATUS_SUCCESS;
    1149         }
     1260            rcHv = GIM_HV_STATUS_INSUFFICIENT_BUFFER;
    11501261    }
    11511262
     
    12171328    else if (cbRead > 0)
    12181329    {
    1219         int rc2 = gimR3HvDebugRead(pVM, pvData, cbRead, pcbReallyRead, cMsTimeout);
     1330        int rc2 = gimR3HvDebugRead(pVM, pvData, GIM_HV_PAGE_SIZE, cbRead, pcbReallyRead, cMsTimeout,
     1331                                   pHv->fIsVendorMsHv /*fUdpPkt*/);
    12201332        Assert(*pcbReallyRead <= cbRead);
    12211333        if (   RT_SUCCESS(rc2)
    12221334            && *pcbReallyRead > 0)
    12231335        {
    1224             uint8_t abFrame[sizeof(RTNETETHERHDR) + RTNETIPV4_MIN_LEN + sizeof(RTNETUDP)];
    1225             if (   pHv->fIsVendorMsHv
    1226                 && *pcbReallyRead + sizeof(abFrame) <= GIM_HV_PAGE_SIZE)
    1227             {
    1228                 /*
    1229                  * Windows guests pumps ethernet frames over the Hyper-V debug connection as
    1230                  * explained in gimR3HvHypercallPostDebugData(). Here, we reconstruct the packet
    1231                  * with the guest's self-chosen IP ARP address we saved in pHv->DbgGuestAddr.
    1232                  *
    1233                  * Note! We really need to pass the minimum IPv4 header length. The Windows 10 guest
    1234                  * is -not- happy if we include the IPv4 options field, i.e. using sizeof(RTNETIPV4)
    1235                  * instead of RTNETIPV4_MIN_LEN.
    1236                  */
    1237                 RT_ZERO(abFrame);
    1238                 PRTNETETHERHDR pEthHdr = (PRTNETETHERHDR)&abFrame[0];
    1239                 PRTNETIPV4     pIpHdr  = (PRTNETIPV4)    (pEthHdr + 1);
    1240                 PRTNETUDP      pUdpHdr = (PRTNETUDP)     ((uint8_t *)pIpHdr + RTNETIPV4_MIN_LEN);
    1241 
    1242                 /* Ethernet */
    1243                 pEthHdr->EtherType = RT_H2N_U16_C(RTNET_ETHERTYPE_IPV4);
    1244                 /* IPv4 */
    1245                 pIpHdr->ip_v       = 4;
    1246                 pIpHdr->ip_hl      = RTNETIPV4_MIN_LEN / sizeof(uint32_t);
    1247                 pIpHdr->ip_tos     = 0;
    1248                 pIpHdr->ip_len     = RT_H2N_U16((uint16_t)*pcbReallyRead + sizeof(RTNETUDP) + RTNETIPV4_MIN_LEN);
    1249                 pIpHdr->ip_id      = 0;
    1250                 pIpHdr->ip_off     = 0;
    1251                 pIpHdr->ip_ttl     = 255;
    1252                 pIpHdr->ip_p       = RTNETIPV4_PROT_UDP;
    1253                 pIpHdr->ip_sum     = 0;
    1254                 pIpHdr->ip_src.u   = 0;
    1255                 pIpHdr->ip_dst.u   = pHv->DbgGuestAddr.u;
    1256                 pIpHdr->ip_sum     = RTNetIPv4HdrChecksum(pIpHdr);
    1257                 /* UDP */
    1258                 pUdpHdr->uh_ulen   = RT_H2N_U16_C((uint16_t)*pcbReallyRead + sizeof(*pUdpHdr));
    1259 
    1260                 /* Make room by moving the payload and prepending the headers. */
    1261                 uint8_t *pbData = (uint8_t *)pvData;
    1262                 memmove(pbData + sizeof(abFrame), pbData, *pcbReallyRead);
    1263                 memcpy(pbData, &abFrame[0], sizeof(abFrame));
    1264 
    1265                 /* Update the adjusted sizes. */
    1266                 *pcbReallyRead += sizeof(abFrame);
    1267                 *pcbRemainingRead = cbRead - *pcbReallyRead;
    1268             }
     1336            *pcbRemainingRead = cbRead -  *pcbReallyRead;
    12691337            rcHv = GIM_HV_STATUS_SUCCESS;
    12701338        }
  • trunk/src/VBox/VMM/include/GIMHvInternal.h

    r58014 r58248  
    243243/** Base address of synthetic interrupt event flag (R/W) */
    244244#define MSR_GIM_HV_SIEFP                          UINT32_C(0x40000082)
    245 /** Base address of synthetic interrupt parameter page (R/W) */
     245/** Base address of synthetic interrupt message page (R/W) */
    246246#define MSR_GIM_HV_SIMP                           UINT32_C(0x40000083)
    247247/** End-Of-Message in synthetic interrupt parameter page (W) */
     
    644644
    645645
    646 /** @name Hyper-V debug support.
     646/** @name Hyper-V MSR - Debug control (MSR_GIM_HV_SYNTH_DEBUG_CONTROL).
     647 * @{
     648 */
     649/** Perform debug write. */
     650#define MSR_GIM_HV_SYNTH_DEBUG_CONTROL_IS_WRITE(a)     RT_BOOL((a) & RT_BIT_64(0))
     651/** Perform debug read. */
     652#define MSR_GIM_HV_SYNTH_DEBUG_CONTROL_IS_READ(a)      RT_BOOL((a) & RT_BIT_64(1))
     653/** Returns length of the debug write buffer. */
     654#define MSR_GIM_HV_SYNTH_DEBUG_CONTROL_W_LEN(a)        (((a) & UINT64_C(0xffff0000)) >> 16)
     655/** @} */
     656
     657
     658/** @name Hyper-V MSR - Debug status (MSR_GIM_HV_SYNTH_DEBUG_STATUS).
     659 * @{
     660 */
     661/** Debug send buffer operation success. */
     662#define MSR_GIM_HV_SYNTH_DEBUG_STATUS_W_SUCCESS_BIT    RT_BIT_32(0)
     663/** Debug receive buffer operation success. */
     664#define MSR_GIM_HV_SYNTH_DEBUG_STATUS_R_SUCCESS_BIT    RT_BIT_32(2)
     665/** Debug connection was reset. */
     666#define MSR_GIM_HV_SYNTH_DEBUG_STATUS_CONN_RESET_BIT   RT_BIT_32(3)
     667/** @} */
     668
     669
     670/** @name Hyper-V hypercall debug support.
    647671 * Options and constants for Hyper-V debug hypercalls.
    648672 * @{
     
    837861    /** @name Guest debugging.
    838862     * @{ */
    839     /** Whether we're posing as the official Microsoft vendor. */
     863    /** Whether we're posing as the Microsoft vendor. */
    840864    bool                        fIsVendorMsHv;
    841     bool                        afAlignment0[7];
     865    /** Whether we're posing as the Microsoft virtualization service. */
     866    bool                        fIsInterfaceVs;
     867    bool                        afAlignment0[6];
    842868    /** The auto IP address last chosen by the guest after failed ARP queries. */
    843869    RTNETADDRIPV4               DbgGuestAddr;
    844870    uint32_t                    uAlignment1;
     871    /** Debug send buffer MSR. */
     872    uint64_t                    uDebugSendBufferMsr;
     873    /** Debug receive buffer MSR. */
     874    uint64_t                    uDebugRecvBufferMsr;
     875    /** Debug pending buffer MSR. */
     876    uint64_t                    uDebugPendingBufferMsr;
     877    /** Debug status MSR. */
     878    uint64_t                    uDebugStatusMsr;
    845879    /** @} */
    846880
     
    864898
    865899#ifdef IN_RING3
    866 VMMR3_INT_DECL(int)             gimR3HvInit(PVM pVM);
     900VMMR3_INT_DECL(int)             gimR3HvInit(PVM pVM, PCFGMNODE pGimCfg);
    867901VMMR3_INT_DECL(int)             gimR3HvInitCompleted(PVM pVM);
    868902VMMR3_INT_DECL(int)             gimR3HvTerm(PVM pVM);
     
    880914VMMR3_INT_DECL(int)             gimR3HvHypercallPostDebugData(PVM pVM, RTGCPHYS GCPhysOut, int *prcHv);
    881915VMMR3_INT_DECL(int)             gimR3HvHypercallRetrieveDebugData(PVM pVM, RTGCPHYS GCPhysOut, int *prcHv);
     916VMMR3_INT_DECL(int)             gimR3HvDebugWrite(PVM pVM, void *pvData, uint32_t cbWrite, uint32_t *pcbWritten, bool fUdpPkt);
     917VMMR3_INT_DECL(int)             gimR3HvDebugRead(PVM pVM, void *pvBuf, uint32_t cbBuf, uint32_t cbRead, uint32_t *pcbRead,
     918                                                 uint32_t cMsTimeout, bool fUdpPkt);
    882919#endif /* IN_RING3 */
    883920
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette