Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

742 lines
17 KiB

  1. //
  2. // Buggy.sys
  3. // Copyright (c) Microsoft Corporation, 1999.
  4. //
  5. // Module: physmem.c
  6. // Author: Silviu Calinoiu (SilviuC)
  7. // Created: 4/20/1999 2:39pm
  8. //
  9. // This module contains stress functions for physical memory
  10. // manipulation routines and also some pool allocaiton routines.
  11. //
  12. // --- History ---
  13. //
  14. // 08/14/99 (SilviuC): initial version (integrating code got from LandyW).
  15. //
  16. #include <ntddk.h>
  17. #include "active.h"
  18. #include "physmem.h"
  19. #if !PHYSMEM_ACTIVE
  20. //
  21. // Dummy implementation if the module is inactive
  22. //
  23. LARGE_INTEGER BuggyOneSecond = {(ULONG)(-10 * 1000 * 1000 * 1), -1};
  24. VOID PhysmemDisabled (VOID)
  25. {
  26. DbgPrint ("Buggy: physmem module is disabled (check \\driver\\active.h header) \n");
  27. }
  28. VOID
  29. StressAllocateContiguousMemory (
  30. PVOID NotUsed
  31. )
  32. {
  33. PhysmemDisabled ();
  34. }
  35. VOID
  36. StressAllocateCommonBuffer (
  37. PVOID NotUsed
  38. )
  39. {
  40. PhysmemDisabled ();
  41. }
  42. VOID
  43. StressAddPhysicalMemory (
  44. PVOID NotUsed
  45. )
  46. {
  47. PhysmemDisabled ();
  48. }
  49. VOID
  50. StressDeletePhysicalMemory (
  51. PVOID NotUsed
  52. )
  53. {
  54. PhysmemDisabled ();
  55. }
  56. VOID
  57. StressLockScenario (
  58. PVOID NotUsed
  59. )
  60. {
  61. PhysmemDisabled ();
  62. }
  63. VOID
  64. StressPhysicalMemorySimple (
  65. PVOID NotUsed
  66. )
  67. {
  68. PhysmemDisabled ();
  69. }
  70. #else
  71. //
  72. // Real implementation if the module is active
  73. //
  74. //////////////////////////
  75. #define MAX_BUFFER_SIZE (2 * 1024 * 1024)
  76. // #define BUFFER_SIZE (32 * 1024)
  77. // ULONG uBufferSize = (64 * 1024);
  78. ULONG uBufferSize = (4 * 1024);
  79. int zlw = 3;
  80. LARGE_INTEGER BuggyTenSeconds = {(ULONG)(-10 * 1000 * 1000 * 10), -1};
  81. LARGE_INTEGER BuggyOneSecond = {(ULONG)(-10 * 1000 * 1000 * 1), -1};
  82. VOID
  83. StressAllocateContiguousMemory (
  84. PVOID NotUsed
  85. )
  86. /*++
  87. Routine Description:
  88. Arguments:
  89. Return Value:
  90. Environment:
  91. --*/
  92. {
  93. PHYSICAL_ADDRESS LogicalAddress;
  94. PVOID VirtualAddress;
  95. ULONG j;
  96. ULONG i;
  97. ULONG k;
  98. PULONG_PTR p;
  99. PVOID MyVirtualAddress[16];
  100. PHYSICAL_ADDRESS MyLogicalAddress[16];
  101. ULONG MySize[16];
  102. PHYSICAL_ADDRESS LowestAcceptableAddress;
  103. PHYSICAL_ADDRESS HighestAcceptableAddress;
  104. PHYSICAL_ADDRESS BoundaryAddressMultiple;
  105. MEMORY_CACHING_TYPE CacheType;
  106. DbgPrint ("Buggy: MmAllocateContiguousMemorySpecifyCache stress ioctl \n");
  107. //
  108. // allocate the buffer
  109. //
  110. uBufferSize = (64 * 1024);
  111. LowestAcceptableAddress.QuadPart = 0;
  112. HighestAcceptableAddress.QuadPart = 0x100000;
  113. BoundaryAddressMultiple.QuadPart = 0;
  114. LogicalAddress.QuadPart = 0;
  115. for (k = 0; k <= 12; k += 1) {
  116. if (k < 4) {
  117. LowestAcceptableAddress.QuadPart = 0;
  118. HighestAcceptableAddress.QuadPart = 0x1000000;
  119. BoundaryAddressMultiple.QuadPart = 0x10000;
  120. }
  121. else if (k < 4) {
  122. LowestAcceptableAddress.QuadPart = 0x1000000;
  123. HighestAcceptableAddress.QuadPart = 0x2000000;
  124. BoundaryAddressMultiple.QuadPart = 0;
  125. }
  126. else {
  127. LowestAcceptableAddress.QuadPart = 0x1800000;
  128. HighestAcceptableAddress.QuadPart = 0x4000000;
  129. BoundaryAddressMultiple.QuadPart = 0x30000;
  130. }
  131. for (CacheType = MmCached; CacheType <= MmWriteCombined; CacheType += 1) {
  132. for (i = 0; i < 16; i += 1) {
  133. DbgPrint( "buffer size = %08X\n", uBufferSize );
  134. if (uBufferSize == 0) {
  135. MyVirtualAddress[i] = NULL;
  136. continue;
  137. }
  138. VirtualAddress = MmAllocateContiguousMemorySpecifyCache (
  139. uBufferSize,
  140. LowestAcceptableAddress,
  141. HighestAcceptableAddress,
  142. BoundaryAddressMultiple,
  143. CacheType);
  144. if (VirtualAddress == NULL) {
  145. DbgPrint( "buggy: MmAllocateContiguousMemSpecifyCache( %08X ) failed\n",
  146. (ULONG) uBufferSize );
  147. // Status = STATUS_DRIVER_INTERNAL_ERROR;
  148. MyVirtualAddress[i] = NULL;
  149. }
  150. else {
  151. DbgPrint( "buggy: MmAllocateContiguousMemSpecifyCache( %p %08X ) - success\n",
  152. VirtualAddress, (ULONG) uBufferSize);
  153. MyVirtualAddress[i] = VirtualAddress;
  154. MyLogicalAddress[i] = LogicalAddress;
  155. MySize[i] = uBufferSize;
  156. p = VirtualAddress;
  157. for (j = 0; j < uBufferSize / sizeof(ULONG_PTR); j += 1) {
  158. *p = ((ULONG_PTR)VirtualAddress + j);
  159. p += 1;
  160. }
  161. }
  162. uBufferSize -= PAGE_SIZE;
  163. }
  164. for (i = 0; i < 16; i += 1) {
  165. if (MyVirtualAddress[i]) {
  166. DbgPrint( "buggy: MmFreeContiguousMemorySpecifyCache( %x %08X )\n",
  167. MyVirtualAddress[i], (ULONG) MySize[i]);
  168. MmFreeContiguousMemorySpecifyCache (MyVirtualAddress[i],
  169. MySize[i],
  170. CacheType);
  171. }
  172. }
  173. }
  174. }
  175. DbgPrint ("Buggy: MmAllocateContiguousMemSpecifyCache test finished\n");
  176. }
  177. VOID
  178. StressAllocateCommonBuffer (
  179. PVOID NotUsed
  180. )
  181. /*++
  182. Routine Description:
  183. Arguments:
  184. Return Value:
  185. Environment:
  186. --*/
  187. {
  188. DEVICE_DESCRIPTION DeviceDescription; // DMA adapter object description
  189. PADAPTER_OBJECT pAdapterObject; // DMA adapter object
  190. ULONG NumberOfMapRegisters;
  191. PHYSICAL_ADDRESS LogicalAddress;
  192. PVOID VirtualAddress;
  193. ULONG j;
  194. ULONG i;
  195. PULONG_PTR p;
  196. PVOID MyVirtualAddress[16];
  197. PHYSICAL_ADDRESS MyLogicalAddress[16];
  198. ULONG MySize[16];
  199. DbgPrint ("Buggy: HalAllocateCommonBuffer stress ioctl \n");
  200. //
  201. // Zero the device description structure.
  202. //
  203. RtlZeroMemory(&DeviceDescription, sizeof(DEVICE_DESCRIPTION));
  204. //
  205. // Get the adapter object for this card.
  206. //
  207. DeviceDescription.Version = DEVICE_DESCRIPTION_VERSION;
  208. DeviceDescription.DmaChannel = 0;
  209. DeviceDescription.InterfaceType = Internal;
  210. DeviceDescription.DmaWidth = Width8Bits;
  211. DeviceDescription.DmaSpeed = Compatible;
  212. DeviceDescription.MaximumLength = MAX_BUFFER_SIZE;
  213. DeviceDescription.BusNumber = 0;
  214. pAdapterObject = HalGetAdapter (&DeviceDescription,
  215. &NumberOfMapRegisters);
  216. if ( pAdapterObject == NULL ) {
  217. DbgPrint( "buggy: HalGetAdapter - failed\n" );
  218. // return STATUS_DRIVER_INTERNAL_ERROR;
  219. return;
  220. }
  221. DbgPrint( "buggy: HalGetAdapter - success\n" );
  222. //
  223. // allocate the buffer
  224. //
  225. uBufferSize = (64 * 1024);
  226. for (i = 0; i < 16; i += 1) {
  227. DbgPrint( "buffer size = %08X\n", uBufferSize );
  228. VirtualAddress = HalAllocateCommonBuffer (pAdapterObject,
  229. uBufferSize,
  230. &LogicalAddress,
  231. FALSE );
  232. if (VirtualAddress == NULL) {
  233. DbgPrint( "buggy: HalAllocateCommonBuffer( %08X ) failed\n",
  234. (ULONG) uBufferSize );
  235. // Status = STATUS_DRIVER_INTERNAL_ERROR;
  236. MyVirtualAddress[i] = NULL;
  237. }
  238. else {
  239. DbgPrint( "buggy: HalAllocateCommonBuffer( %p %08X ) - success\n",
  240. VirtualAddress, (ULONG) uBufferSize);
  241. MyVirtualAddress[i] = VirtualAddress;
  242. MyLogicalAddress[i] = LogicalAddress;
  243. MySize[i] = uBufferSize;
  244. p = VirtualAddress;
  245. for (j = 0; j < uBufferSize / sizeof(ULONG_PTR); j += 1) {
  246. *p = ((ULONG_PTR)VirtualAddress + j);
  247. p += 1;
  248. }
  249. }
  250. uBufferSize -= PAGE_SIZE;
  251. }
  252. for (i = 0; i < 16; i += 1) {
  253. if (MyVirtualAddress[i]) {
  254. DbgPrint( "buggy: HalFreeCommonBuffer( %x %08X )\n",
  255. MyVirtualAddress[i], (ULONG) MySize[i]);
  256. HalFreeCommonBuffer(
  257. pAdapterObject,
  258. MySize[i],
  259. MyLogicalAddress[i],
  260. MyVirtualAddress[i],
  261. FALSE );
  262. }
  263. }
  264. DbgPrint ("Buggy: HalAllocateCommonBuffer test finished\n");
  265. // LWFIX: Halfreeadapter needed ?
  266. }
  267. LOGICAL StopToEdit = TRUE;
  268. PFN_NUMBER TestBasePage;
  269. PFN_NUMBER TestPageCount;
  270. VOID
  271. EditPhysicalMemoryParameters (
  272. )
  273. /*++
  274. Routine Description:
  275. This function is called from StressAdd/DeletePhysicalMemory
  276. to allow user to set the parameters for stress (what region should
  277. be used for add/remove ?).
  278. Arguments:
  279. None.
  280. Return Value:
  281. None.
  282. Environment:
  283. Kernel mode.
  284. --*/
  285. {
  286. DbgPrint ("`dd nt!mmphysicalmemoryblock l1' should give the address of memory descriptor\n");
  287. DbgPrint ("`dd ADDRESS' (first dword displayed by previous command) gives description\n");
  288. DbgPrint ("The structure of the memory descriptor is presented below: \n");
  289. DbgPrint ("(4) NoOfRuns \n");
  290. DbgPrint ("(4) NoOfPages \n");
  291. DbgPrint ("(4) Run[0]: BasePage \n");
  292. DbgPrint ("(4) Run[0]: PageCount \n");
  293. DbgPrint ("(4) Run[1]: ... \n");
  294. DbgPrint ("(4) ... \n");
  295. DbgPrint (" \n");
  296. DbgPrint ("When you decide on values you should edit the following: \n");
  297. DbgPrint ("buggy!StopToEdit <- 0 \n");
  298. DbgPrint ("buggy!TestBasePage <- decided value \n");
  299. DbgPrint ("buggy!TestPageCount <- decided value \n");
  300. DbgPrint (" \n");
  301. DbgBreakPoint ();
  302. }
  303. VOID
  304. StressAddPhysicalMemory (
  305. PVOID NotUsed
  306. )
  307. /*++
  308. Routine Description:
  309. This function regresses the MmAddPhysicalMemory kernel API.
  310. It does not really stress it but rather iterate through some
  311. possible combinations.
  312. Arguments:
  313. None.
  314. Return Value:
  315. None.
  316. Environment:
  317. Kernel mode.
  318. --*/
  319. {
  320. NTSTATUS Status;
  321. ULONG i;
  322. PHYSICAL_ADDRESS StartAddress;
  323. LARGE_INTEGER NumberOfBytes;
  324. DbgPrint ("Buggy: add physical memory stress ioctl \n");
  325. //
  326. // (SilviuC): We need an automatic way to figure out memory runs.
  327. //
  328. if (StopToEdit) {
  329. EditPhysicalMemoryParameters ();
  330. }
  331. StartAddress.QuadPart = (LONGLONG)TestBasePage * PAGE_SIZE;
  332. NumberOfBytes.QuadPart = (LONGLONG)TestPageCount * PAGE_SIZE;
  333. i = 0;
  334. do {
  335. i += 1;
  336. DbgPrint ("buggy: MmAddPhysicalMemory0 %x %x %x %x\n",
  337. StartAddress.HighPart,
  338. StartAddress.LowPart,
  339. NumberOfBytes.HighPart,
  340. NumberOfBytes.LowPart);
  341. Status = MmAddPhysicalMemory (
  342. &StartAddress,
  343. &NumberOfBytes);
  344. DbgPrint ("buggy: MmAddPhysicalMemory %x %x %x %x %x\n",
  345. Status,
  346. StartAddress.HighPart,
  347. StartAddress.LowPart,
  348. NumberOfBytes.HighPart,
  349. NumberOfBytes.LowPart);
  350. if ((i % 8) == 0) {
  351. KeDelayExecutionThread (KernelMode, FALSE, &BuggyTenSeconds);
  352. }
  353. StartAddress.QuadPart -= NumberOfBytes.QuadPart;
  354. } while (StartAddress.QuadPart > 0);
  355. DbgPrint ("Buggy: MmAddPhysicalMemory test finished\n");
  356. }
  357. VOID
  358. StressDeletePhysicalMemory (
  359. PVOID NotUsed
  360. )
  361. /*++
  362. Routine Description:
  363. This function regresses the MmRemovePhysicalMemory kernel API.
  364. It does not really stress the function but rather iterate
  365. throughout the physical memory and attempt to remove chunks of it.
  366. Arguments:
  367. None.
  368. Return Value:
  369. None.
  370. Environment:
  371. Kernel mode.
  372. --*/
  373. {
  374. NTSTATUS Status;
  375. ULONG i;
  376. PHYSICAL_ADDRESS StartAddress;
  377. LARGE_INTEGER NumberOfBytes;
  378. //
  379. // SilviuC: we need an automatic way to figure out memory runs.
  380. //
  381. if (StopToEdit) {
  382. EditPhysicalMemoryParameters ();
  383. }
  384. StartAddress.QuadPart = (LONGLONG)TestBasePage * PAGE_SIZE;
  385. NumberOfBytes.QuadPart = (LONGLONG)TestPageCount * PAGE_SIZE;
  386. for (i = 0; i < (0xf0000000 / NumberOfBytes.LowPart); i += 1) {
  387. DbgPrint ("buggy: MmRemovePhysicalMemory0 %x %x %x %x\n",
  388. StartAddress.HighPart,
  389. StartAddress.LowPart,
  390. NumberOfBytes.HighPart,
  391. NumberOfBytes.LowPart);
  392. Status = MmRemovePhysicalMemory (
  393. &StartAddress,
  394. &NumberOfBytes);
  395. DbgPrint ("buggy: MmRemovePhysicalMemory %x %x %x %x %x\n",
  396. Status,
  397. StartAddress.HighPart,
  398. StartAddress.LowPart,
  399. NumberOfBytes.HighPart,
  400. NumberOfBytes.LowPart);
  401. StartAddress.QuadPart += NumberOfBytes.QuadPart;
  402. if ((i % 8) == 0) {
  403. KeDelayExecutionThread (KernelMode, FALSE, &BuggyTenSeconds);
  404. }
  405. }
  406. DbgPrint ("Buggy: MmRemovePhysicalMemory test finished\n");
  407. }
  408. //
  409. // Global:
  410. //
  411. // BigData
  412. //
  413. // Description:
  414. //
  415. // Dummy pageable array needed to test lock/unlock scenarios.
  416. //
  417. NTSTATUS
  418. DriverEntry (
  419. IN PDRIVER_OBJECT DriverObject,
  420. IN PUNICODE_STRING RegistryPath
  421. );
  422. #ifdef ALLOC_PRAGMA
  423. #pragma data_seg("BDAT")
  424. ULONG BigData [0x10000];
  425. #pragma data_seg()
  426. #endif // #ifdef ALLOC_PRAGMA
  427. VOID
  428. StressLockScenario (
  429. PVOID NotUsed
  430. )
  431. /*++
  432. Routine Description:
  433. Arguments:
  434. Return Value:
  435. Environment:
  436. --*/
  437. {
  438. ULONG I;
  439. PVOID Handle;
  440. #if 0
  441. for (I = 0; I < 16; I++) {
  442. Handle = MmLockPagableDataSection (BigData);
  443. DbgPrint ("Buggy: lock handle %p \n", Handle);
  444. MmUnlockPagableImageSection (Handle);
  445. }
  446. #else
  447. for (I = 0; I < 16; I++) {
  448. MmPageEntireDriver (DriverEntry);
  449. MmResetDriverPaging (BigData);
  450. }
  451. #endif
  452. }
  453. VOID
  454. StressPhysicalMemorySimple (
  455. PVOID NotUsed
  456. )
  457. /*++
  458. Routine Description:
  459. This routine exercises add/remove physical memory functions
  460. using a simple remove scenario.
  461. Note. This function contributed by LandyW.
  462. Arguments:
  463. None.
  464. Return Value:
  465. None.
  466. Environment:
  467. Kernel mode.
  468. --*/
  469. {
  470. #if 0
  471. ULONG i;
  472. PPHYSICAL_MEMORY_RANGE Ranges;
  473. PPHYSICAL_MEMORY_RANGE p;
  474. PHYSICAL_ADDRESS StartAddress;
  475. LARGE_INTEGER NumberOfBytes;
  476. PHYSICAL_ADDRESS InputAddress;
  477. LARGE_INTEGER InputBytes;
  478. Ranges = MmGetPhysicalMemoryRanges ();
  479. if (Ranges == NULL) {
  480. DbgPrint ("Buggy: MmRemovePhysicalMemory cannot get ranges\n");
  481. Status = STATUS_INSUFFICIENT_RESOURCES;
  482. return;
  483. }
  484. p = Ranges;
  485. while (p->BaseAddress.QuadPart != 0 && p->NumberOfBytes.QuadPart != 0) {
  486. StartAddress.QuadPart = p->BaseAddress.QuadPart;
  487. NumberOfBytes.QuadPart = p->NumberOfBytes.QuadPart;
  488. InputAddress.QuadPart = StartAddress.QuadPart;
  489. InputBytes.QuadPart = NumberOfBytes.QuadPart;
  490. if (InputBytes.QuadPart > (128 * 1024 * 1024)) {
  491. InputBytes.QuadPart = (128 * 1024 * 1024);
  492. }
  493. while (InputAddress.QuadPart + InputBytes.QuadPart <=
  494. StartAddress.QuadPart + NumberOfBytes.QuadPart) {
  495. DbgPrint ("buggy: MmRemovePhysicalMemory0 %x %x %x %x\n",
  496. InputAddress.HighPart,
  497. InputAddress.LowPart,
  498. InputBytes.HighPart,
  499. InputBytes.LowPart);
  500. Status = MmRemovePhysicalMemory (&InputAddress,
  501. &InputBytes);
  502. DbgPrint ("buggy: MmRemovePhysicalMemory %x %x %x %x %x\n\n",
  503. Status,
  504. InputAddress.HighPart,
  505. InputAddress.LowPart,
  506. InputBytes.HighPart,
  507. InputBytes.LowPart);
  508. KeDelayExecutionThread (KernelMode, FALSE, &BuggyOneSecond);
  509. if (NT_SUCCESS(Status)) {
  510. DbgPrint ("buggy: MmAddPhysicalMemory0 %x %x %x %x\n",
  511. InputAddress.HighPart,
  512. InputAddress.LowPart,
  513. InputBytes.HighPart,
  514. InputBytes.LowPart);
  515. Status = MmAddPhysicalMemory (
  516. &InputAddress,
  517. &InputBytes);
  518. if (NT_SUCCESS(Status)) {
  519. DbgPrint ("\n\n***************\nbuggy: MmAddPhysicalMemory WORKED %x %x %x %x %x\n****************\n",
  520. Status,
  521. InputAddress.HighPart,
  522. InputAddress.LowPart,
  523. InputBytes.HighPart,
  524. InputBytes.LowPart);
  525. }
  526. else {
  527. DbgPrint ("buggy: MmAddPhysicalMemory FAILED %x %x %x %x %x\n\n",
  528. Status,
  529. InputAddress.HighPart,
  530. InputAddress.LowPart,
  531. InputBytes.HighPart,
  532. InputBytes.LowPart);
  533. DbgBreakPoint ();
  534. }
  535. }
  536. if (InputAddress.QuadPart + InputBytes.QuadPart ==
  537. StartAddress.QuadPart + NumberOfBytes.QuadPart) {
  538. break;
  539. }
  540. InputAddress.QuadPart += InputBytes.QuadPart;
  541. if (InputAddress.QuadPart + InputBytes.QuadPart >
  542. StartAddress.QuadPart + NumberOfBytes.QuadPart) {
  543. InputBytes.QuadPart = StartAddress.QuadPart + NumberOfBytes.QuadPart - InputAddress.QuadPart;
  544. }
  545. }
  546. p += 1;
  547. }
  548. ExFreePool (Ranges);
  549. DbgPrint ("Buggy: Add/remove physical memory simple stress finished\n");
  550. #endif // #if 0
  551. }
  552. #endif // #if !PHYSMEM_ACTIVE