1 /* 2 * Copyright (c) 2014-2019, Intel Corporation 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * * Redistributions of source code must retain the above copyright notice, 8 * this list of conditions and the following disclaimer. 9 * * Redistributions in binary form must reproduce the above copyright notice, 10 * this list of conditions and the following disclaimer in the documentation 11 * and/or other materials provided with the distribution. 12 * * Neither the name of Intel Corporation nor the names of its contributors 13 * may be used to endorse or promote products derived from this software 14 * without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include "ptunit.h" 30 31 #include "pt_asid.h" 32 33 #include "intel-pt.h" 34 35 #include <stddef.h> 36 37 38 static struct ptunit_result from_user_null(void) 39 { 40 struct pt_asid user; 41 int errcode; 42 43 pt_asid_init(&user); 44 45 errcode = pt_asid_from_user(NULL, NULL); 46 ptu_int_eq(errcode, -pte_internal); 47 48 errcode = pt_asid_from_user(NULL, &user); 49 ptu_int_eq(errcode, -pte_internal); 50 51 return ptu_passed(); 52 } 53 54 static struct ptunit_result from_user_default(void) 55 { 56 struct pt_asid asid; 57 int errcode; 58 59 errcode = pt_asid_from_user(&asid, NULL); 60 ptu_int_eq(errcode, 0); 61 ptu_uint_eq(asid.size, sizeof(asid)); 62 ptu_uint_eq(asid.cr3, pt_asid_no_cr3); 63 ptu_uint_eq(asid.vmcs, pt_asid_no_vmcs); 64 65 return ptu_passed(); 66 } 67 68 static struct ptunit_result from_user_small(void) 69 { 70 struct pt_asid asid, user; 71 int errcode; 72 73 user.size = sizeof(user.size); 74 75 errcode = pt_asid_from_user(&asid, &user); 76 ptu_int_eq(errcode, 0); 77 ptu_uint_eq(asid.size, sizeof(asid)); 78 ptu_uint_eq(asid.cr3, pt_asid_no_cr3); 79 ptu_uint_eq(asid.vmcs, pt_asid_no_vmcs); 80 81 return ptu_passed(); 82 } 83 84 static struct ptunit_result from_user_big(void) 85 { 86 struct pt_asid asid, user; 87 int errcode; 88 89 user.size = sizeof(user) + 4; 90 user.cr3 = 0x4200ull; 91 user.vmcs = 0x23000ull; 92 93 errcode = pt_asid_from_user(&asid, &user); 94 ptu_int_eq(errcode, 0); 95 ptu_uint_eq(asid.size, sizeof(asid)); 96 ptu_uint_eq(asid.cr3, 0x4200ull); 97 ptu_uint_eq(asid.vmcs, 0x23000ull); 98 99 return ptu_passed(); 100 } 101 102 static struct ptunit_result from_user(void) 103 { 104 struct pt_asid asid, user; 105 int errcode; 106 107 user.size = sizeof(user); 108 user.cr3 = 0x4200ull; 109 user.vmcs = 0x23000ull; 110 111 errcode = pt_asid_from_user(&asid, &user); 112 ptu_int_eq(errcode, 0); 113 ptu_uint_eq(asid.size, sizeof(asid)); 114 ptu_uint_eq(asid.cr3, 0x4200ull); 115 ptu_uint_eq(asid.vmcs, 0x23000ull); 116 117 return ptu_passed(); 118 } 119 120 static struct ptunit_result from_user_cr3(void) 121 { 122 struct pt_asid asid, user; 123 int errcode; 124 125 user.size = offsetof(struct pt_asid, vmcs); 126 user.cr3 = 0x4200ull; 127 user.vmcs = 0x23000ull; 128 129 errcode = pt_asid_from_user(&asid, &user); 130 ptu_int_eq(errcode, 0); 131 ptu_uint_eq(asid.size, sizeof(asid)); 132 ptu_uint_eq(asid.cr3, 0x4200ull); 133 ptu_uint_eq(asid.vmcs, pt_asid_no_vmcs); 134 135 return ptu_passed(); 136 } 137 138 static struct ptunit_result to_user_null(void) 139 { 140 struct pt_asid asid; 141 int errcode; 142 143 pt_asid_init(&asid); 144 145 errcode = pt_asid_to_user(NULL, NULL, sizeof(asid)); 146 ptu_int_eq(errcode, -pte_internal); 147 148 errcode = pt_asid_to_user(NULL, &asid, sizeof(asid)); 149 ptu_int_eq(errcode, -pte_internal); 150 151 return ptu_passed(); 152 } 153 154 static struct ptunit_result to_user_too_small(void) 155 { 156 struct pt_asid asid, user; 157 int errcode; 158 159 pt_asid_init(&asid); 160 161 errcode = pt_asid_to_user(&user, &asid, 0); 162 ptu_int_eq(errcode, -pte_invalid); 163 164 errcode = pt_asid_to_user(&user, &asid, sizeof(user.size) - 1); 165 ptu_int_eq(errcode, -pte_invalid); 166 167 return ptu_passed(); 168 } 169 170 static struct ptunit_result to_user_small(void) 171 { 172 struct pt_asid asid, user; 173 int errcode; 174 175 memset(&user, 0xcc, sizeof(user)); 176 pt_asid_init(&asid); 177 178 errcode = pt_asid_to_user(&user, &asid, sizeof(user.size)); 179 ptu_int_eq(errcode, 0); 180 ptu_uint_eq(user.size, sizeof(user.size)); 181 ptu_uint_eq(user.cr3, 0xccccccccccccccccull); 182 ptu_uint_eq(user.vmcs, 0xccccccccccccccccull); 183 184 return ptu_passed(); 185 } 186 187 static struct ptunit_result to_user_big(void) 188 { 189 struct pt_asid asid, user; 190 int errcode; 191 192 memset(&user, 0xcc, sizeof(user)); 193 pt_asid_init(&asid); 194 asid.cr3 = 0x4200ull; 195 asid.vmcs = 0x23000ull; 196 197 errcode = pt_asid_to_user(&user, &asid, sizeof(user) + 8); 198 ptu_int_eq(errcode, 0); 199 ptu_uint_eq(user.size, sizeof(asid)); 200 ptu_uint_eq(user.cr3, 0x4200ull); 201 ptu_uint_eq(user.vmcs, 0x23000ull); 202 203 return ptu_passed(); 204 } 205 206 static struct ptunit_result to_user(void) 207 { 208 struct pt_asid asid, user; 209 int errcode; 210 211 memset(&user, 0xcc, sizeof(user)); 212 pt_asid_init(&asid); 213 asid.cr3 = 0x4200ull; 214 asid.vmcs = 0x23000ull; 215 216 errcode = pt_asid_to_user(&user, &asid, sizeof(user)); 217 ptu_int_eq(errcode, 0); 218 ptu_uint_eq(user.size, sizeof(asid)); 219 ptu_uint_eq(user.cr3, 0x4200ull); 220 ptu_uint_eq(user.vmcs, 0x23000ull); 221 222 return ptu_passed(); 223 } 224 225 static struct ptunit_result to_user_cr3(void) 226 { 227 struct pt_asid asid, user; 228 int errcode; 229 230 memset(&user, 0xcc, sizeof(user)); 231 pt_asid_init(&asid); 232 asid.cr3 = 0x4200ull; 233 234 errcode = pt_asid_to_user(&user, &asid, offsetof(struct pt_asid, vmcs)); 235 ptu_int_eq(errcode, 0); 236 ptu_uint_eq(user.size, offsetof(struct pt_asid, vmcs)); 237 ptu_uint_eq(user.cr3, 0x4200ull); 238 ptu_uint_eq(user.vmcs, 0xccccccccccccccccull); 239 240 return ptu_passed(); 241 } 242 243 static struct ptunit_result match_null(void) 244 { 245 struct pt_asid asid; 246 int errcode; 247 248 pt_asid_init(&asid); 249 250 errcode = pt_asid_match(NULL, NULL); 251 ptu_int_eq(errcode, -pte_internal); 252 253 errcode = pt_asid_match(NULL, &asid); 254 ptu_int_eq(errcode, -pte_internal); 255 256 errcode = pt_asid_match(&asid, NULL); 257 ptu_int_eq(errcode, -pte_internal); 258 259 return ptu_passed(); 260 } 261 262 static struct ptunit_result match_default(void) 263 { 264 struct pt_asid lhs, rhs; 265 int errcode; 266 267 pt_asid_init(&lhs); 268 pt_asid_init(&rhs); 269 270 errcode = pt_asid_match(&lhs, &rhs); 271 ptu_int_eq(errcode, 1); 272 273 lhs.cr3 = 0x2300ull; 274 lhs.vmcs = 0x42000ull; 275 276 errcode = pt_asid_match(&lhs, &rhs); 277 ptu_int_eq(errcode, 1); 278 279 errcode = pt_asid_match(&rhs, &lhs); 280 ptu_int_eq(errcode, 1); 281 282 return ptu_passed(); 283 } 284 285 static struct ptunit_result match_default_mixed(void) 286 { 287 struct pt_asid lhs, rhs; 288 int errcode; 289 290 pt_asid_init(&lhs); 291 pt_asid_init(&rhs); 292 293 errcode = pt_asid_match(&lhs, &rhs); 294 ptu_int_eq(errcode, 1); 295 296 lhs.cr3 = 0x2300ull; 297 rhs.vmcs = 0x42000ull; 298 299 errcode = pt_asid_match(&lhs, &rhs); 300 ptu_int_eq(errcode, 1); 301 302 errcode = pt_asid_match(&rhs, &lhs); 303 ptu_int_eq(errcode, 1); 304 305 return ptu_passed(); 306 } 307 308 static struct ptunit_result match_cr3(void) 309 { 310 struct pt_asid lhs, rhs; 311 int errcode; 312 313 pt_asid_init(&lhs); 314 pt_asid_init(&rhs); 315 316 lhs.cr3 = 0x2300ull; 317 rhs.cr3 = 0x2300ull; 318 319 errcode = pt_asid_match(&lhs, &rhs); 320 ptu_int_eq(errcode, 1); 321 322 return ptu_passed(); 323 } 324 325 static struct ptunit_result match_vmcs(void) 326 { 327 struct pt_asid lhs, rhs; 328 int errcode; 329 330 pt_asid_init(&lhs); 331 pt_asid_init(&rhs); 332 333 lhs.vmcs = 0x23000ull; 334 rhs.vmcs = 0x23000ull; 335 336 errcode = pt_asid_match(&lhs, &rhs); 337 ptu_int_eq(errcode, 1); 338 339 return ptu_passed(); 340 } 341 342 static struct ptunit_result match(void) 343 { 344 struct pt_asid lhs, rhs; 345 int errcode; 346 347 pt_asid_init(&lhs); 348 pt_asid_init(&rhs); 349 350 lhs.cr3 = 0x2300ull; 351 rhs.cr3 = 0x2300ull; 352 lhs.vmcs = 0x23000ull; 353 rhs.vmcs = 0x23000ull; 354 355 errcode = pt_asid_match(&lhs, &rhs); 356 ptu_int_eq(errcode, 1); 357 358 return ptu_passed(); 359 } 360 361 static struct ptunit_result match_cr3_false(void) 362 { 363 struct pt_asid lhs, rhs; 364 int errcode; 365 366 pt_asid_init(&lhs); 367 pt_asid_init(&rhs); 368 369 lhs.cr3 = 0x4200ull; 370 rhs.cr3 = 0x2300ull; 371 372 errcode = pt_asid_match(&lhs, &rhs); 373 ptu_int_eq(errcode, 0); 374 375 return ptu_passed(); 376 } 377 378 static struct ptunit_result match_vmcs_false(void) 379 { 380 struct pt_asid lhs, rhs; 381 int errcode; 382 383 pt_asid_init(&lhs); 384 pt_asid_init(&rhs); 385 386 lhs.vmcs = 0x42000ull; 387 rhs.vmcs = 0x23000ull; 388 389 errcode = pt_asid_match(&lhs, &rhs); 390 ptu_int_eq(errcode, 0); 391 392 return ptu_passed(); 393 } 394 395 int main(int argc, char **argv) 396 { 397 struct ptunit_suite suite; 398 399 suite = ptunit_mk_suite(argc, argv); 400 401 ptu_run(suite, from_user_null); 402 ptu_run(suite, from_user_default); 403 ptu_run(suite, from_user_small); 404 ptu_run(suite, from_user_big); 405 ptu_run(suite, from_user); 406 ptu_run(suite, from_user_cr3); 407 408 ptu_run(suite, to_user_null); 409 ptu_run(suite, to_user_too_small); 410 ptu_run(suite, to_user_small); 411 ptu_run(suite, to_user_big); 412 ptu_run(suite, to_user); 413 ptu_run(suite, to_user_cr3); 414 415 ptu_run(suite, match_null); 416 ptu_run(suite, match_default); 417 ptu_run(suite, match_default_mixed); 418 ptu_run(suite, match_cr3); 419 ptu_run(suite, match_vmcs); 420 ptu_run(suite, match); 421 ptu_run(suite, match_cr3_false); 422 ptu_run(suite, match_vmcs_false); 423 424 return ptunit_report(&suite); 425 } 426