aboutsummaryrefslogtreecommitdiffstats
path: root/package/kernel/mac80211/patches/ath9k/547-ath9k_led_defstate_fix.patch
Commit message (Expand)AuthorAgeFilesLines
* mac80211: split ath patch in dedicated subdirAnsuel Smith2021-06-041-0/+29
n61'>61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279
/*
 * Definitions and utilities for save / restore.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation;
 * version 2.1 of the License.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "xc_private.h"

#include <xen/foreign/x86_32.h>
#include <xen/foreign/x86_64.h>

/*
 * SAVE/RESTORE/MIGRATE PROTOCOL
 * =============================
 *
 * The general form of a stream of chunks is a header followed by a
 * body consisting of a variable number of chunks (terminated by a
 * chunk with type 0) followed by a trailer.
 *
 * For a rolling/checkpoint (e.g. remus) migration then the body and
 * trailer phases can be repeated until an external event
 * (e.g. failure) causes the process to terminate and commit to the
 * most recent complete checkpoint.
 *
 * HEADER
 * ------
 *
 * unsigned long        : p2m_size
 *
 * extended-info (PV-only, optional):
 *
 *   If first unsigned long == ~0UL then extended info is present,
 *   otherwise unsigned long is part of p2m. Note that p2m_size above
 *   does not include the length of the extended info.
 *
 *   extended-info:
 *
 *     unsigned long    : signature == ~0UL
 *     uint32_t	        : number of bytes remaining in extended-info
 *
 *     1 or more extended-info blocks of form:
 *     char[4]          : block identifier
 *     uint32_t         : block data size
 *     bytes            : block data
 *
 *     defined extended-info blocks:
 *     "vcpu"		: VCPU context info containing vcpu_guest_context_t.
 *                        The precise variant of the context structure
 *                        (e.g. 32 vs 64 bit) is distinguished by
 *                        the block size.
 *     "extv"           : Presence indicates use of extended VCPU context in
 *                        tail, data size is 0.
 *
 * p2m (PV-only):
 *
 *   consists of p2m_size bytes comprising an array of xen_pfn_t sized entries.
 *
 * BODY PHASE
 * ----------
 *
 * A series of chunks with a common header:
 *   int              : chunk type
 *
 * If the chunk type is +ve then chunk contains guest memory data, and the
 * type contains the number of pages in the batch:
 *
 *     unsigned long[]  : PFN array, length == number of pages in batch
 *                        Each entry consists of XEN_DOMCTL_PFINFO_*
 *                        in bits 31-28 and the PFN number in bits 27-0.
 *     page data        : PAGE_SIZE bytes for each page marked present in PFN
 *                        array
 *
 * If the chunk type is -ve then chunk consists of one of a number of
 * metadata types.  See definitions of XC_SAVE_ID_* below.
 *
 * If chunk type is 0 then body phase is complete.
 *
 * TAIL PHASE
 * ----------
 *
 * Content differs for PV and HVM guests.
 *
 * HVM TAIL:
 *
 *  "Magic" pages:
 *     uint64_t         : I/O req PFN
 *     uint64_t         : Buffered I/O req PFN
 *     uint64_t         : Store PFN
 *  Xen HVM Context:
 *     uint32_t         : Length of context in bytes
 *     bytes            : Context data
 *  Qemu context:
 *     char[21]         : Signature:
 *       "QemuDeviceModelRecord" : Read Qemu save data until EOF
 *       "DeviceModelRecord0002" : uint32_t length field followed by that many
 *                                 bytes of Qemu save data
 *       "RemusDeviceModelState" : Currently the same as "DeviceModelRecord0002".
 *
 * PV TAIL:
 *
 *  Unmapped PFN list   : list of all the PFNs that were not in map at the close
 *     unsigned int     : Number of unmapped pages
 *     unsigned long[]  : PFNs of unmapped pages
 *
 *  VCPU context data   : A series of VCPU records, one per present VCPU
 *                        Maximum and present map supplied in XC_SAVE_ID_VCPUINFO
 *     bytes:           : VCPU context structure. Size is determined by size
 *                        provided in extended-info header
 *     bytes[128]       : Extended VCPU context (present IFF "extv" block
 *                        present in extended-info header)
 *
 *  Shared Info Page    : 4096 bytes of shared info page
 */

#define XC_SAVE_ID_ENABLE_VERIFY_MODE -1 /* Switch to validation phase. */
#define XC_SAVE_ID_VCPU_INFO          -2 /* Additional VCPU info */
#define XC_SAVE_ID_HVM_IDENT_PT       -3 /* (HVM-only) */
#define XC_SAVE_ID_HVM_VM86_TSS       -4 /* (HVM-only) */
#define XC_SAVE_ID_TMEM               -5
#define XC_SAVE_ID_TMEM_EXTRA         -6
#define XC_SAVE_ID_TSC_INFO           -7
#define XC_SAVE_ID_HVM_CONSOLE_PFN    -8 /* (HVM-only) */
#define XC_SAVE_ID_LAST_CHECKPOINT    -9 /* Commit to restoring after completion of current iteration. */
#define XC_SAVE_ID_HVM_ACPI_IOPORTS_LOCATION -10

/*
** We process save/restore/migrate in batches of pages; the below
** determines how many pages we (at maximum) deal with in each batch.
*/
#define MAX_BATCH_SIZE 1024   /* up to 1024 pages (4MB) at a time */

/* When pinning page tables at the end of restore, we also use batching. */
#define MAX_PIN_BATCH  1024



/*
** Determine various platform information required for save/restore, in
** particular:
**
**    - the maximum MFN on this machine, used to compute the size of
**      the M2P table;
**
**    - the starting virtual address of the the hypervisor; we use this
**      to determine which parts of guest address space(s) do and don't
**      require canonicalization during save/restore; and
**
**    - the number of page-table levels for save/ restore. This should
**      be a property of the domain, but for the moment we just read it
**      from the hypervisor.
**
**    - The width of a guest word (unsigned long), in bytes.
**
** Returns 1 on success, 0 on failure.
*/
static inline int get_platform_info(xc_interface *xch, uint32_t dom,
                                    /* OUT */ unsigned long *max_mfn,
                                    /* OUT */ unsigned long *hvirt_start,
                                    /* OUT */ unsigned int *pt_levels,
                                    /* OUT */ unsigned int *guest_width)
{
    xen_capabilities_info_t xen_caps = "";
    xen_platform_parameters_t xen_params;
    DECLARE_DOMCTL;

    if (xc_version(xch, XENVER_platform_parameters, &xen_params) != 0)
        return 0;

    if (xc_version(xch, XENVER_capabilities, &xen_caps) != 0)
        return 0;

    *max_mfn = xc_maximum_ram_page(xch);

    *hvirt_start = xen_params.virt_start;

    memset(&domctl, 0, sizeof(domctl));
    domctl.domain = dom;
    domctl.cmd = XEN_DOMCTL_get_address_size;

    if ( do_domctl(xch, &domctl) != 0 )
        return 0; 

    *guest_width = domctl.u.address_size.size / 8;

    /* 64-bit tools will see the 64-bit hvirt_start, but 32-bit guests 
     * will be using the compat one. */
    if ( *guest_width < sizeof (unsigned long) )
        /* XXX need to fix up a way of extracting this value from Xen if
         * XXX it becomes variable for domU */
        *hvirt_start = 0xf5800000;

    if (strstr(xen_caps, "xen-3.0-x86_64"))
        /* Depends on whether it's a compat 32-on-64 guest */
        *pt_levels = ( (*guest_width == 8) ? 4 : 3 );
    else if (strstr(xen_caps, "xen-3.0-x86_32p"))
        *pt_levels = 3;
    else if (strstr(xen_caps, "xen-3.0-x86_32"))
        *pt_levels = 2;
    else
        return 0;

    return 1;
}


/*
** Save/restore deal with the mfn_to_pfn (M2P) and pfn_to_mfn (P2M) tables.
** The M2P simply holds the corresponding PFN, while the top bit of a P2M
** entry tell us whether or not the the PFN is currently mapped.
*/

#define PFN_TO_KB(_pfn) ((_pfn) << (PAGE_SHIFT - 10))


/*
** The M2P is made up of some number of 'chunks' of at least 2MB in size.
** The below definitions and utility function(s) deal with mapping the M2P
** regarldess of the underlying machine memory size or architecture.
*/
#define M2P_SHIFT       L2_PAGETABLE_SHIFT_PAE
#define M2P_CHUNK_SIZE  (1 << M2P_SHIFT)
#define M2P_SIZE(_m)    ROUNDUP(((_m) * sizeof(xen_pfn_t)), M2P_SHIFT)
#define M2P_CHUNKS(_m)  (M2P_SIZE((_m)) >> M2P_SHIFT)

/* Returns TRUE if the PFN is currently mapped */
#define is_mapped(pfn_type) (!((pfn_type) & 0x80000000UL))


#define GET_FIELD(_p, _f) ((dinfo->guest_width==8) ? ((_p)->x64._f) : ((_p)->x32._f))

#define SET_FIELD(_p, _f, _v) do {              \
    if (dinfo->guest_width == 8)                \
        (_p)->x64._f = (_v);                    \
    else                                        \
        (_p)->x32._f = (_v);                    \
} while (0)

#define UNFOLD_CR3(_c)                                                  \
  ((uint64_t)((dinfo->guest_width == 8)                                 \
              ? ((_c) >> 12)                                            \
              : (((uint32_t)(_c) >> 12) | ((uint32_t)(_c) << 20))))

#define FOLD_CR3(_c)                                                    \
  ((uint64_t)((dinfo->guest_width == 8)                                 \
              ? ((uint64_t)(_c)) << 12                                  \
              : (((uint32_t)(_c) << 12) | ((uint32_t)(_c) >> 20))))

#define MEMCPY_FIELD(_d, _s, _f) do {                              \
    if (dinfo->guest_width == 8)                                   \
        memcpy(&(_d)->x64._f, &(_s)->x64._f,sizeof((_d)->x64._f)); \
    else                                                           \
        memcpy(&(_d)->x32._f, &(_s)->x32._f,sizeof((_d)->x32._f)); \
} while (0)

#define MEMSET_ARRAY_FIELD(_p, _f, _v) do {                        \
    if (dinfo->guest_width == 8)                                   \
        memset(&(_p)->x64._f[0], (_v), sizeof((_p)->x64._f));      \
    else                                                           \
        memset(&(_p)->x32._f[0], (_v), sizeof((_p)->x32._f));      \
} while (0)

#ifndef MAX
#define MAX(_a, _b) ((_a) >= (_b) ? (_a) : (_b))
#endif
#ifndef MIN
#define MIN(_a, _b) ((_a) <= (_b) ? (_a) : (_b))
#endif