Open hariv opened 2 years ago
Hi @hariv
The DRAM address functions are obtained from an i7-8700K (Coffee Lake). It is very likely that those functions are different on other CPUs. In this case, you would need to first-reverse engineer them (e.g., using DRAMA or TRRespass' DRAMA) and then update the DRAM addressing matrices in DRAMAddr.cpp.
Got it. Thank you @pjattke.
Hi @hariv
The DRAM address functions are obtained from an i7-8700K (Coffee Lake). It is very likely that those functions are different on other CPUs. In this case, you would need to first-reverse engineer them (e.g., using DRAMA or TRRespass' DRAMA) and then update the DRAM addressing matrices in DRAMAddr.cpp.
Hi. @pjattke. I've got the following TRRespass's DRAMA outcome on a skylake machine. can you explain how DRAMAddr.cpp should be modified to reflect the mapping? Thanks.
Valid Function: 0x4080 bits: 7 + 14
Valid Function: 0x88000 bits: 15 + 19
Valid Function: 0x110000 bits: 16 + 20
Valid Function: 0x220000 bits: 17 + 21
Valid Function: 0x440000 bits: 18 + 22
Valid Function: 0x4b300 bits: 8 + 9 + 12 + 13 + 15 + 18
0x4080
0x88000
0x110000
0x220000
0x440000
0x4b300
Could we get any followup on this? I used DRAMA tool as well and obtained memory functions, but don't know how to input them into the code.
Dear @heechul and @DominikBucko,
I'm sorry for the late reply but I didn't have time to work on that yet. I'll soon (in the next days) provide you with a script that generates the addressing matrices that you can input into Blacksmith.
Thanks for your patience and understanding!
Dear @heechul and @DominikBucko,
Finally, I managed to find some time to update our DRAM addressing matrices script. Sorry for the delay.
You can find the script mat-gen.py
in this gist. You can find a # TODO
note showing the section that you need to edit. It should be enough if you fill out dram_fns
and row_fn
based on the information from DRAMA.
Regards, Patrick
Hi @pjattke
Thanks a lot for sharing the script. I have a question.
If I'm not mistaken, the output of the script seems a bit different from the default configuration in the blacksmith repository when dram_fns and row_fn in the script was configured to match with the known functions in the repository (i.e., dram_fns = [0x2040, 0x24000, 0x48000, 0x90000], row_fn = 0x3ffe0000). For example, in the aforementioned single_rank configuration, DRAM_MTX[4] - DRAM_MTX[10] are shifted right by 1 bit in the generated matrix compared to the matrix in the code repository. Can you clarify on this?
Thanks
Heechul.
Hi @heechul
To summarize what my colleague told me, who has implemented this part of Blacksmith:
It shouldn't matter all that much because changing one bit changes also the other one if you want to stay in the same bank, so it's either/or. If we assume we have the row/col bit overlapping with a bank function (multiple XORed bits), then having that row bit on the higher bit or the lower bit shouldn't matter since you can't change one without changing the other.
This is because the bank/rank functions on our CPU (i7-8700K) consist each of two bits that are combined by XOR. So if you change any of them, you will end up in a different bank.
However, coming back to your question: I cannot tell why the output is different (shifted by one bit). My colleague told me that he will look into this more once he finds time. Meanwhile, you can just try to use the output generated by mat-gen.py and report back if that worked for you.
In any way, I will try to replace this DRAM addressing part in the next couple of weeks by something that makes it easier to work with as I recognize that the current solution is cumbersome.
Hi @pjattke
Thanks for following this up.
struct MemConfiguration single_rank= {
..
// bank_rank_functions = std::vector<uint64_t>({0x2040, 0x24000, 0x48000, 0x90000});
.DRAM_MTX = { /* addr -> bank (4 bits) | col (13 bits) | row (13 bits) */
0b000000000000000010000001000000, /* 0x02040 bank b3 = addr b6 + b13 */
0b000000000000100100000000000000, /* 0x24000 bank b2 = addr b14 + b17 */
0b000000000001001000000000000000, /* 0x48000 bank b1 = addr b15 + b18 */
0b000000000010010000000000000000, /* 0x90000 bank b0 = addr b16 + b19 */
0b000000000000000010000000000000, /* col b12 = addr b13 */
0b000000000000000001000000000000, /* col b11 = addr b12 */
0b000000000000000000100000000000, /* col b10 = addr b11 */
0b000000000000000000010000000000, /* col b9 = addr b10 */
0b000000000000000000001000000000, /* col b8 = addr b9 */
0b000000000000000000000100000000, /* col b7 = addr b8*/
0b000000000000000000000010000000, /* col b6 = addr b7 */
0b000000000000000000000000100000, /* col b5 = addr b5 (not b6)*/
0b000000000000000000000000010000, /* col b4 = addr b4*/
0b000000000000000000000000001000, /* col b3 = addr b3 */
0b000000000000000000000000000100, /* col b2 = addr b2 */
0b000000000000000000000000000010, /* col b1 = addr b1 */
0b000000000000000000000000000001, /* col b0 = addr b0*/
0b100000000000000000000000000000, /* row b12 = addr b29 */
0b010000000000000000000000000000, /* row b11 = addr b28 */
0b001000000000000000000000000000, /* row b10 = addr b27 */
0b000100000000000000000000000000, /* row b9 = addr b26 */
0b000010000000000000000000000000, /* row b8 = addr b25 */
0b000001000000000000000000000000, /* row b7 = addr b24 */
0b000000100000000000000000000000, /* row b6 = addr b23 */
0b000000010000000000000000000000, /* row b5 = addr b22 */
0b000000001000000000000000000000, /* row b4 = addr b21 */
0b000000000100000000000000000000, /* row b3 = addr b20 */
0b000000000010000000000000000000, /* row b2 = addr b19 */
0b000000000001000000000000000000, /* row b1 = addr b18 */
0b000000000000100000000000000000, /* row b0 = addr b17 */
},
.ADDR_MTX = { /* bank | col | row --> addr */
0b000000000000000001000000000000, /* addr b29 = row b12 */
0b000000000000000000100000000000, /* addr b28 = row b11 */
0b000000000000000000010000000000, /* addr b27 = row b10 */
0b000000000000000000001000000000, /* addr b26 = row b9 */
0b000000000000000000000100000000, /* addr b25 = row b8 */
0b000000000000000000000010000000, /* addr b24 = row b7 */
0b000000000000000000000001000000, /* addr b23 = row b6 */
0b000000000000000000000000100000, /* addr b22 = row b5 */
0b000000000000000000000000010000, /* addr b21 = row b4 */
0b000000000000000000000000001000, /* addr b20 = row b3 */
0b000000000000000000000000000100, /* addr b19 = row b2 */
0b000000000000000000000000000010, /* addr b18 = row b1 */
0b000000000000000000000000000001, /* addr b17 = row b0 */
0b000100000000000000000000000100, /* addr b16 = bank b0 + row b2 (addr b19) */
0b001000000000000000000000000010, /* addr b15 = bank b1 + row b1 (addr b18) */
0b010000000000000000000000000001, /* addr b14 = bank b2 + row b0 (addr b17) */
0b000010000000000000000000000000, /* addr b13 = col b12 */
0b000001000000000000000000000000, /* addr b12 = col b11 */
0b000000100000000000000000000000, /* addr b11 = col b10 */
0b000000010000000000000000000000, /* addr b10 = col b9 */
0b000000001000000000000000000000, /* addr b9 = col b8 */
0b000000000100000000000000000000, /* addr b8 = col b7 */
0b000000000010000000000000000000, /* addr b7 = col b6 */
0b100010000000000000000000000000, /* addr b6 = bank b3 + col b12 (addr b13)*/
0b000000000001000000000000000000, /* addr b5 = col b5 */
0b000000000000100000000000000000, /* addr b4 = col b4 */
0b000000000000010000000000000000, /* addr b3 = col b3 */
0b000000000000001000000000000000, /* addr b2 = col b2 */
0b000000000000000100000000000000, /* addr b1 = col b1 */
0b000000000000000010000000000000 /* addr b0 = col b0 */
}
Thanks
Dear @heechul,
Thanks for your update.
mat-gen.py
? It would be helpful to know that so I can start integrating mat-gen.py
more properly.mat-gen.py
in case they use a CPU with a different micro-architecture). As a first step towards making this easier, I have added a CPU model check in Blacksmith.cpp
. Regards, Patrick
Hi @pjattke
Thanks for confirming the annotation. I can report that we got bitflips with the mat-gen.py generated matrices. Thanks for the pointers regarding Skylake mapping functions.
Happy new year! Heechul
Hi Patrik,
for an i3-8350k system I have created a log with DRAMA, see attachment.
Unfortunately I don't know how to get the values for dram_fns
and row-fn
out of this information.
Could you explain how to determine these?
Hi @JKRde,
Could you meanwhile figure it out or do you need help? Basically, you need to take the bits DRAMA found to be part of the masks, then create its hexadecimal representation, and then use the mat-gen.py
script to translate the masks into the DRAM addressing matrices used by Blacksmith.
Hi Patrik,
Unfortunately I have not yet managed to determine the dram_fns
& row_fn
values with the TRRespass' DRAMA tools. Maybe you could give me a step by step guide for dummies ;-)
BR Jens
Hi @pjattke , I have run the drama from Trrespass repo and get the result of DRAM mapping function info as below.
~~~~~~~~~~ Found Functions ~~~~~~~~~~
Valid Function: 0x8000 bits: 15
Valid Function: 0x10000 bits: 16
Valid Function: 0x20080 bits: 7 + 17
Valid Function: 0x1000040 bits: 6 + 24
Valid Function: 0x2200000 bits: 21 + 25
Valid Function: 0x4400000 bits: 22 + 26
Valid Function: 0x8800000 bits: 23 + 27
Valid Function: 0x145140 bits: 6 + 8 + 12 + 14 + 18 + 20
0x8000
0x10000
0x20080
0x1000040
0x2200000
0x4400000
0x8800000
0x145140
~~~~~~~~~~ Looking for row bits ~~~~~~~~~~
[LOG] - Set #0
[LOG] - 184716da80 - 18824693eb Time: 273 <== GOTCHA
[LOG] - 184716da80 - 18553ecda1 Time: 270 <== GOTCHA
[LOG] - 184716da80 - 18160cf469 Time: 270 <== GOTCHA
[LOG] - 184716da80 - 189352a594 Time: 267 <== GOTCHA
[LOG] - 184716da80 - 180714b92f Time: 264 <== GOTCHA
[LOG] - Set #1
[LOG] - 1833714c40 - 18541b138a Time: 273 <== GOTCHA
[LOG] - 1833714c40 - 1899d90349 Time: 276 <== GOTCHA
[LOG] - 1833714c40 - 18373f65f1 Time: 279 <== GOTCHA
[LOG] - 1833714c40 - 1808cd7a0f Time: 279 <== GOTCHA
[LOG] - 1833714c40 - 1822712c20 Time: 279 <== GOTCHA
[LOG] - Row mask: 0xffff800000 bits: 23 + 24 + 25 + 26 + 27 + 28 + 29 + 30 + 31 + 32 + 33 + 34 + 35 + 36 + 37 + 38 + 39
0xffff800000
Continuously, I parse them into the script mat-gen.py as below.
num_channels = 4
num_dimms = 16
num_ranks = 2
num_banks = 16
dram_fns = [0x8000, 0x10000, 0x20080, 0x1000040, 0x2200000, 0x4400000, 0x8800000, 0x145140]
row_fn = 0xffff800000
col_fn = 8192 - 1
However, the script mat-gen.py will throw the error because https://gist.github.com/pjattke/b56baff62be77f16ad8d33376789be67#file-mat-gen-py-L56 requires a 30x30 square which is not satisfied by my drama result and parsed info in mat-gen.py. I'm confused with that is 30x30 enforced? Obviously, my daram result is not.
Hi @TheSilentDawn. Thanks for your interest in Blacksmith. Could you please provide us with some more information:
The 30x30
constraint comes from the fact that we are using a superpage, and thus cannot control any bits higher than bit 30. It needs to be a square matrix and invertible (i.e., have full rank) such that we can compute the
Best Patrick
Hi @pjattke , Thanks for your prompt reply.
num_channels = 1
num_dimms = 1
num_ranks = 2
num_banks = 16
I rerun drama from trrespass. The result is below.
root@ubuntu: ~/trrespass-master/drama/obj#./tester -s 16 -t 460 -o access.csv -v
...
~~~~~~~~~~ Found Functions ~~~~~~~~~~
Valid Function: 0x2000 bits: 13
Valid Function: 0x200040 bits: 6 + 21
Valid Function: 0x440000 bits: 18 + 22
Valid Function: 0x880000 bits: 19 + 23
Valid Function: 0x1100000 bits: 20 + 24
0x2000
0x200040
0x440000
0x880000
0x1100000
~~~~~~~~~~ Looking for row bits ~~~~~~~~~~
[LOG] - Set #0
[LOG] - 3d6b5b940 - 3bb6a30f0 Time: 413 <== GOTCHA
[LOG] - 3d6b5b940 - 39cb725cd Time: 407 <== GOTCHA
[LOG] - 3d6b5b940 - 3aa59e8af Time: 458 <== GOTCHA
[LOG] - 3d6b5b940 - 3e097750e Time: 458 <== GOTCHA
[LOG] - 3d6b5b940 - 3961e2b9a Time: 458 <== GOTCHA
[LOG] - Set #1
[LOG] - 3c86ac200 - 3e0485651 Time: 458 <== GOTCHA
[LOG] - 3c86ac200 - 3e8c106cb Time: 458 <== GOTCHA
[LOG] - 3c86ac200 - 3b1f18208 Time: 458 <== GOTCHA
[LOG] - 3c86ac200 - 3f53f1a9f Time: 458 <== GOTCHA
[LOG] - 3c86ac200 - 3ddf18e91 Time: 458 <== GOTCHA
[LOG] - Row mask: 0xffff000000 bits: 24 + 25 + 26 + 27 + 28 + 29 + 30 + 31 + 32 + 33 + 34 + 35 + 36 + 37 + 38 + 39
0xffff000000
Based on my understanding the variable dram_fns in mat-gen.py should be configurated as [0x2000, 0x200040, 0x440000, 0x880000, 0x1100000] and the variable row_fn should be configurated as 0xffff000000 following the result from trrespass drama. However, I'm confused with the variable col_fn, which value should it be? If I try to create a 30x30 matrix, it should be 524288 - 1. But the script mat-gen.py will throw an error meaning not invertible.
Hi @pjattke , I also got another result running on Intel(R) Xeon(R) CPU E5-2690 and 1x16G DRAM which Part Number is HMT42GR7BFR4A-PB. The drama output is below.
xxx:~/trrespass-master/drama # ./obj/tester -s 8 -o ddr3.csv -v
~~~~~~~~~~ Found Functions ~~~~~~~~~~
Valid Function: 0x4000 bits: 14
Valid Function: 0x80000 bits: 19
Valid Function: 0x42000 bits: 13 + 18
0x4000
0x80000
0x42000
~~~~~~~~~~ Looking for row bits ~~~~~~~~~~
[LOG] - Set #0
[LOG] - 2d9cde780 - 2fe09de11 Time: 288 <== GOTCHA
[LOG] - 2d9cde780 - 2de7842b5 Time: 280 <== GOTCHA
[LOG] - 2d9cde780 - 2a4b8df0f Time: 272 <== GOTCHA
[LOG] - 2d9cde780 - 2e74ac4b4 Time: 280 <== GOTCHA
[LOG] - 2d9cde780 - 2b10de59e Time: 304 <== GOTCHA
[LOG] - Set #1
[LOG] - 2f0f163c0 - 2b636d892 Time: 280 <== GOTCHA
[LOG] - 2f0f163c0 - 2af73e536 Time: 304 <== GOTCHA
[LOG] - 2f0f163c0 - 29eb7593b Time: 284 <== GOTCHA
[LOG] - 2f0f163c0 - 2d2d4c2c3 Time: 284 <== GOTCHA
[LOG] - 2f0f163c0 - 2f3074bc3 Time: 276 <== GOTCHA
[LOG] - Row mask: 0xffff000000 bits: 24 + 25 + 26 + 27 + 28 + 29 + 30 + 31 + 32 + 33 + 34 + 35 + 36 + 37 + 38 + 39
0xffff000000
Could you please help to explain what configuration should be in mat-gen.py?
Hi @TheSilentDawn. I'm sorry, but I do not have the resources anytime in near future to help with this further. There is a little chance that one of my students will have the time to make mat-gen.py
nice over the next weeks, but I cannot promise.
You will need to study the mat-gen.py
carefully. It's basically just a translation matrix that it computes, so you need to have a square matrix (e.g., 30x30) with full rank (i.e., linearly independent rows). If this is not given, you either have the wrong functions (or row/column masks), or you need to augment it with "dummy" matrix rows (this would correspond to bits not involved in DRAM addressing).
I'm sorry that I cannot give you a more positive reply. I hope you understand. Good luck!
@pjattke We have a student who is using blacksmith in a project. As part of the project he did some polishing on the address function import part of blacksmith and will post a PR soon.
Has anyone successfully caused bitflips on DRAMs produced by Blacksmith between 2023-2024 ? I ran the project without any error message, but I didn't flip any bits on any DRAMs.Has this method now become impossible to bypass the existing TRR mechanism?
Hi @missyoufenglan87, we have also found more recent DIMMs where we could not trigger bit flips with Blacksmith anymore. We have not investigated this further on a larger scale though. It is likely that the DRAM vendors meanwhile have improved their mitigations.
Great work and this repo is the best and the only we can Confirmed Reproduce.
Memory Module: HMA81GU6JJR8N-VK This is a Rank 1 Bank 8 module. PC Model: OptiPlex-7060 Detailed Computer Spec: dmidecode.txt OS: Ubuntu 22.04
Steps:
TRespass/drama/hugepage.sh
. Run again if computer rebooted, you can ignore the error saying directory existed.TRespass/drama/obj/tester -s 16 --mem 1024000
. This step shall generate result fairly quick. We expect the whole process done in 30 seconds. If not, kill it and try again. We sometime observe the result is offset to most of the results, we don't know why. Our results are 0x2040,0x24000,0x48000,0x90000
(use for dram_fns) and 0x3ffe0000
(use for row_fn). blacksmith/src/Memory/DRAMAddr.cpp
with generated content. We have also updated blacksmith/include/GlobalDefines.hpp
to match our module. updated_files.zipsudo blacksmith/build/blacksmith --dimm-id 1 --ranks 1 -t 2160000
Logs: stdout.zip
Did anyone try running blacksmith on CPUs other than Coffee Lake?
I was able to run it successfully on Kaby Lake, but it didn't work on Comet Lake. It errors out immediately saying it could not find conflicting address sets and asks if the number of banks has been defined correctly (which I checked is correct).