I have the following issue: I want to define the clock a CPU should use during frequency transitions in the device tree rather than in the clock driver code (in this way it will be more generic). I want to define the "transition-clock" property in the device tree, something like:
232 cpu: cpu#01c20050 {
233 #clock-cells = <0>;
234 compatible = "allwinner,sun4i-a10-cpu-clk";
235 reg = <0x01c20050 0x4>;
-----
243 clocks = <&osc32k>, <&osc24M>, <&pll1>, <&pll1>;
244 transition-clock = <&osc24M>;
245 clock-output-names = "cpu";
246 };
I changed the file "drivers/clk/clkdev.c" to search this property so I can get a clk pointer and store it in a new property in the cpu clock structure. This is what I have managed so far (changes begin on line 78):
59 static struct clk *__of_clk_get(struct device_node *np, int index,
60 const char *dev_id, const char *con_id)
61 {
62 struct of_phandle_args clkspec;
63 struct clk *clk, *transition_clk;
64 struct device_node *clock_node, *transition_clock_node;
65 int rc;
66
67 if (index < 0)
68 return ERR_PTR(-EINVAL);
69
70 rc = of_parse_phandle_with_args(np, "clocks", "#clock-cells", index,
71 &clkspec);
72 if (rc)
73 return ERR_PTR(rc);
74
75 clk = __of_clk_get_by_clkspec(&clkspec, dev_id, con_id);
76 of_node_put(clkspec.np);
77
78 clock_node = of_parse_phandle(np, "clocks", 0);
79 pr_err("-------------------- parsing node %s\n", np->name);
80 if (clock_node!=NULL) {
81 pr_err("============ Clock node found %p\n", clock_node);
82 transition_clock_node =
83 of_parse_phandle(clock_node, "transition-clock", 0);
84 if (transition_clock_node!=NULL) {
85 pr_err("============ Transition clock node found %p\n",
86 transition_clock_node);
87 transition_clk = clk_get(clock_node, 0);
88 pr_err("============ Transition clock %p\n", transition_clk);
89 }
90 }
91
92 return clk;
93 }
I get pointers to the clock node and the transition clock node, but when I try to get a clock pointer from that, I get 0xfffffffe, which looks like an error:
[ 2.540542] -------------------- parsing node cpu
[ 2.540546] ============ Clock node found eeef9520
[ 2.540550] ============ Transition clock node found eeef8934
[ 2.540555] ============ Transition clock fffffffe
I want a clock object which I can later use in
clk_set_parent(cpu_clk, cpu_clk->transition_clk)
Any ideas are welcome :)
OK, I got it figured out in the meantime and since nobody answered I'm going to provide my solution (maybe somebody else bumps into this issue):
81 if (clock_node != NULL) {
82 rc = of_parse_phandle_with_args(clock_node, "transition-clock", NULL,
83 0, &transition_clkspec);
84 of_node_put(transition_clkspec.np);
85
86 if (!rc) {
87 transition_clock = __of_clk_get_by_clkspec(&transition_clkspec,
88 dev_id, con_id);
89 clk_set_transition_parent(clk, transition_clock);
90 }
91 }
So, the solution is to get an object of type "of_phandle_args" and get the clock from there using __of_clk_get_by_clkspec.
(the clk_set_transition_parent function is defined somewhere else and it does exactly what it's name suggests)
Related
I am currently working with oneof properties. I am able to encode them without issue, however, decoding seems to be an issue. I fail to understand why it doesn't work.
My proto file looks like this:
syntax = "proto2";
message stringCallback{
required string name = 1;
required string surname = 2;
required int32 age = 3;
repeated sint32 values = 4;
repeated metrics metric_data = 5;
oneof payload {
int32 i_val = 6;
float f_val = 7;
string msg = 8;
}
}
message metrics{
required int32 id = 1;
required string type = 2;
required sint32 value = 3;
}
Whenever I send from a C# application a message containing in the payload an integer, there is no issue decoding. I get the right int value and which_payload value as well.
I then tried to send a float. This resulted in a value which was not corresponding to the value I send through C# (which makes sense because I use the "standard decoder" which means that it treats it as an int instead of a fixed32) I don't know how to tell the decoder to decode this value with the fixed32 option.
And finally sending a payload which contains a message resulted in an incorrect which_payload value (Type None: 0) and no corresponding message. Even though before the decode function I assigned a callback function to decode a string (works perfectly).
Additional info:
This is the byte array which I send to the Nanopb code containing a string in the payload:
0A 04 4B 65 65 73 12 07 76 61 6E 20 44 61 6D 18 34 20 02 20 04 20 06 20 08 20 0A 20 0C 20 0E 20 10 20 12 20 14 20 16 20 18 2A 0C 08 01 12 06 53 65 6E 73 6F 72 18 04 2A 0A 08 02 12 04 44 61 74 61 18 0A 2A 0E 08 03 12 08 57 69 72 65 6C 65 73 73 18 0E 2A 0D 08 04 12 07 54 65 73 74 69 6E 67 18 04 2A 10 08 05 12 0A 46 72 6F 6E 74 20 64 6F 6F 72 18 0A 2A 1B 08 06 12 15 54 68 69 73 20 69 73 20 61 20 72 61 6E 64 6F 6D 20 6E 61 6D 65 18 0E 42 10 48 65 6C 6C 6F 20 66 72 6F 6D 20 6F 6E 65 6F 66
I get from an online decoder the correct decoded variables but not on Nanopb. What am I supposed to do?
EDIT:
As per request, my decoder test function:
void test_decode(byte* payload, unsigned int length){
IntArray I_array = {0, 0};
MetricArray M_array = {0,0};
char name[MAX_STRING_LENGTH];
char surname[MAX_STRING_LENGTH];
char msg[MAX_STRING_LENGTH];
stringCallback message = stringCallback_init_zero;
message.name.funcs.decode = String_decode;
message.name.arg = &name;
message.surname.funcs.decode = String_decode;
message.surname.arg = &surname;
message.values.funcs.decode = IntArray_decode;
message.values.arg = &I_array;
message.metric_data.funcs.decode = MetricArray_decode;
message.metric_data.arg = &M_array;
message.payload.msg.arg = &msg;
message.payload.msg.funcs.decode = String_decode;
pb_istream_t istream = pb_istream_from_buffer(payload, length);
if(!pb_decode(&istream, stringCallback_fields, &message)){
Serial.println("Total decoding failed!");
return;
}
Serial.println(name);
Serial.println(surname);
Serial.println(message.age);
Serial.println(I_array.count);
Serial.println(M_array.count);
Serial.println();
MetricArray_print(&M_array);
Serial.println();
Serial.println("Oneof: ");
Serial.println(message.which_payload);
}
After some searching and testing I found a workaround!
I look at these examples, and figured that there are possibilities of having callbacks in oneof fields. There is a possibility to add a Nanopb option to the proto file which tells the message that it should generate a callback.
The option:
option (nanopb_msgopt).submsg_callback = true;
By adding this line to the proto file it will generate (to my understanding) a set-up callback. This callback gets called at the start of decoding the message. This gives us the opportunity to setup different callbacks for different fields in the oneof depending on the type we are decoding.
The problem before with oneof is that it was impossible to assign callback functions to the fields of the oneof type since they all share the same memory space. But by having this set-up callback we can actually have a look at what we are receiving and assign a callback accordingly.
However, there is a catch. I found out that this option will not work on anything other than messages in the oneof. This means no direct callback type can be assigned to a oneof field!
The workaround I used is to encapsulate the wanted callback in a message. This will trigger the set-up callback which then can be used to assign the correct callback function in the oneof.
EXAMPLE:
Lets take this proto file:
syntax = "proto2";
message callback{
required string name = 1;
required string surname = 2;
required int32 age = 3;
repeated sint32 values = 4;
repeated metrics metric_data = 5;
oneof payload {
int32 i_val = 6;
float f_val = 7;
string msg = 8;
payloadmsg p_msg = 9;
payloadmsg2 p_msg2 = 10;
}
}
message metrics{
required int32 id = 1;
required string type = 2;
required sint32 value = 3;
}
message payloadmsg{
required int32 id = 1;
required string type = 2;
required string msg = 3;
repeated sint32 values = 4;
}
message payloadmsg2{
required int32 id = 1;
required string type = 2;
required string msg = 3;
repeated sint32 values = 4;
}
I gave the strings in this proto file a maximum length which removed their callback type and exchanged it for a character array.
For testing purposes I didn't assign a size to the integer arrays in the payloadmsg messages.
The goal is to decode the arrays stored in the payloadmsg messages depending on the oneof type received (payloadmsg or payloadmsg2)
Then the set-up callback has to be created:
bool Oneof_decode(pb_istream_t *stream, const pb_field_t *field, void** arg){
Callback* msg = (Callback*)field->message;
switch(field->tag){
case stringCallback_p_msg_tag:{
Serial.println("Oneof type: p_msg detected!");
payloadmsg* p_message = (payloadmsg*)field->pData;
IntArray* array = (IntArray*)*arg;
p_message->values.arg = array;
p_message->values.funcs.decode = IntArray_decode;
break;
}
case stringCallback_p_msg2_tag:{
Serial.println("Oneof type: p_msg2 detected!");
payloadmsg2* p_message2 = (payloadmsg2*)field->pData;
IntArray* array = (IntArray*)*arg;
p_message2->values.arg = array;
p_message2->values.funcs.decode = IntArray_decode;
break;
}
}
return true;
}
We look at the tag we receive while decoding to see which type of callback has to be assigned. This is done by accessing the field. By using a switch case we can decide, according to the field tag, what decode callback function to assign. We pass the arguments and decoder functions like normal, after that everything is set-up correctly.
Finally we assign this callback set-up to the compiler generated variable called cb_payload. This variable will be added to your message struct when you put in the option in the protofile. This is how to assign the set-up callback:
message.cb_payload.arg = &I_array;
message.cb_payload.funcs.decode = Oneof_decode;
pb_istream_t istream = pb_istream_from_buffer(payload, length);
if(!pb_decode(&istream, stringCallback_fields, &message)){
Serial.println("Total decoding failed!");
return;
}
I pass my own IntArray struct to the cb_payload function as an argument to then pass it on to the correctly assigned decoder.
The result is that whenever I decode payloadmsg or payloadmsg2 the correct decoder gets assigned and the right values are being decoded into the structs.
from my previsou question Why does module failed to load? (/dev/scull0 : no such device or address) I managed to load the module via /sbin/insmod, but after that, I have log out the dmesg:
[ 2765.707018] scull: loading out-of-tree module taints kernel.
[ 2765.707106] scull: module verification failed: signature and/or required key missing - tainting kernel
[ 2765.707929] Passed scull_init_module at 41 (debug info - successful load of init module)
[ 6027.843914] acer_wmi: Unknown function number - 8 - 1
[ 7347.683312] stack segment: 0000 [#1] SMP PTI
[ 7347.683323] CPU: 3 PID: 15280 Comm: rmmod Tainted: G OE 4.19.0-9-amd64 #1 Debian 4.19.118-2
[ 7347.683326] Hardware name: Acer Swift SF314-52/Suntory_KL, BIOS V1.08 11/28/2017
/* start of the problem: */
[ 7347.683335] RIP: 0010:scull_trim+0x3a/0xa0 [scull]
[ 7347.683339] Code: 44 8b 77 0c 48 8b 2f 45 8d 66 ff 49 c1 e4 03 48 85 ed 75 16 eb 4b 48 8b 5d 08 48 89 ef e8 7e 38 f1 e1 48 89 dd 48 85 db 74 37 <48> 8b 7d 00 48 85 ff 74 e3 45 85 f6 7e 1a 31 db eb 04 48 83 c3 08
/*... output of all registers ...*/
[ 7347.683372] Call Trace:
[ 7347.683382] cleanup_module+0x44/0x80 [scull]
[ 7347.683391] __x64_sys_delete_module+0x190/0x2e0
[ 7347.683399] do_syscall_64+0x53/0x110
[ 7347.683405] entry_SYSCALL_64_after_hwframe+0x44/0xa9
[ 7347.683530] ---[ end trace c4b4a1cdb428d4b3 ]---
[ 7347.885914] RIP: 0010:scull_trim+0x3a/0xa0 [scull]
... /* again */ ...
Here I can observer, the mess is caused by the scull_trim (source below), and kernel trigger strace to resolve it (or does kernel call Call Trace: when something goes bad in kernel?).
scull_trim:
/*main structure */
struct scull_dev {
struct scull_qset *data; /*quantum repre*/
int quantum; /*in bytes*/
int qset; /*array size*/
unsigned long size; /*total bytes in device*/
struct cdev cdev; /*Char device structure*/
};
/*representation of quantum*/
struct scull_qset {
void **data;
struct scull_qset *next;
};
/*-------------------------------------------------------------------------------------*/
int scull_trim(struct scull_dev *dev) {
struct scull_qset *next, *dptr; /* next for loop, dptr = data pointer (index in loop) */
int qset = dev->qset; /* get size of arrat */
int i; /*index for second loop for quantum bytes */
for(dptr = dev->data /*struct scull_qset*/; dptr ; dptr = next){
if (dptr->data /*array of quantum*/) {
for(i=0; i<qset; i++){
kfree(dptr->data[i]); /*free each byte of array data[i]*/
}
kfree(dptr->data); /*free array pointer itself*/
dptr->data = NULL; /*set array pointer to null pointer to avoid garbage*/
}
next = dptr->next;
kfree(dptr); /* free pointer itself */
}
//setting new attributes for cleared dev
dev->size = 0;
dev->quantum = scull_quantum;
dev->qset = scull_qset;
dev->data = NULL;
return 0;
}
The function scull_trim is basically from linux device driver, 3 edition, And the function's intend is to get rid of all bytes from the device before open method is called. But why does it caused the dmesg error in that, kernel had to call strace to resolve it?
EDIT:
Because it is nearly impossible to resolve the problem, I am adding source (as well as dmesg dump) from github:
repo:scull device. Please visit it to resolve the issue.
I'm using bufbomb.c to do some buffer overflow attack experimenting.
I successfully used gdb to debug the code. Howeverer; when I run the program directly, I get a "Segmentation fault (core dumped)" when I enter the characters to try the attack.
I used gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1. to build the following.
//bufbomb.c
/* Bomb program that is solved using a buffer overflow attack */
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
/* Like gets, except that characters are typed as pairs of hex digits.
Nondigit characters are ignored. Stops when encounters newline */
char *getxs(char *dest)
{
int c;
int even =1; /* Have read even number of digits */
int otherd =0; /* Other hex digit of pair */
char*sp = dest;
while ((c = getchar()) != EOF && c !='\n') {
if (isxdigit(c)) {
int val;
if ('0'<= c && c <='9')
val = c -'0';
else if ('A'<= c && c <='F')
val = c -'A'+10;
else
val = c -'a'+10;
if (even) {
otherd = val;
even =0;
}
else {
*sp++= otherd *16+ val;
even =1;
}
}
}
*sp++='\0';
return dest;
}
/* $begin getbuf-c */
int getbuf()
{
char buf[12];
getxs(buf);
return 1;
}
void test()
{
int val;
printf("Type Hex string:");
val = getbuf();
printf("getbuf returned 0x%x\n", val);
}
/* $end getbuf-c */
int main()
{
int buf[16];
/* This little hack is an attempt to get the stack to be in a
stable position
*/
int offset = (((int) buf) &0xFFF);
int*space = (int*) alloca(offset);
*space =0; /* So that don't get complaint of unused variable */
test();
return 0;
}
Then I executed it under gdb:
...> gdb ./bugbomb
...
..run
Type Hex string:30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 d8 bf ff ff 9f 85 04 08 b0 86 04 08 30 31 32 33 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 ef be ad de
getbuf returned 0xdeadbeef
[Inferior 1 (process 13530) exited normally]
And then without gdb::
./bufbomb
Type Hex string:30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 d8 bf ff ff 9f 85 04 08 b0 86 04 08 30 31 32 33 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 ef be ad de
Segmentation fault (core dumped)
I am looking for some help to resolve the seg-fault.
Run it under gdb with a bigger buffer to see which address it's trying to access to guess the stack offset of the return address used by getbuf().
To bear with small differences in memory offsets that arise from the use of gdb, use a NOP-sled. Your attack buffer should look like this:
|RET ADDRESS x 30 | NOPS (0x90) x 1000 | SHELLCODE|.
The return address should point to the middle of the NOP-sled.
If the execution jumps anywhere in the sled, it will slide to the shellcode.
You are accessing memory that your process doesn't "own".
When you run gdb, the compiler adds stuff (like extra debug info).
You can bypass the segmentation fault by expanding the stack before you attempt the buffer overflow:
int expand_stack(int n_bytes)
{
char buf[n_bytes];
return buf[n_bytes-1]; // access the memory to make sure the optimiser doesn't remove buf.
}
And in main, add a call to expand_stack before you call test:
int main()
{
int buf[16];
/* This little hack is an attempt to get the stack to be in a
stable position
*/
int offset = (((int) buf) &0xFFF);
int*space = (int*) alloca(offset);
*space = expand_stack(200);
test();
return 0;
}
Note that your code still invokes undefined behaviour.
Note2: If your compiler doesn't support variable length arrays, just use a fixed array, buf[200].
I am starting to learn to write PCI driver and the first exercise i took was to find if a given device exists on the bus. After searching some books and internet, i was able to write down the below program which does work but i am not clear on few concepts.
1 /*
2 Program to find a device on the PCI sub-system
3 */
4 #define VENDOR_ID 0x8086
5 #define DEVICE_ID 0x7113
6
7 #include <linux/kernel.h>
8 #include <linux/module.h>
9 #include <linux/stddef.h>
10 #include <linux/pci.h>
11 #include <linux/init.h>
12 #include <linux/cdev.h>
13 #include <linux/device.h>
14
15 #define LOG(string...) printk(KERN_NOTICE string)
16
17 #define CDEV_MAJOR 227
18 #define CDEV_MINOR 0
19
20
21 MODULE_LICENSE("GPL");
22
23 struct pci_dev *pci_dev;
24 unsigned long mmio_addr;
25 unsigned long reg_len;
26 unsigned long *base_addr;
27
28 int device_probe(struct pci_dev *dev, const struct pci_device_id *id);
29 void device_remove(struct pci_dev *dev);
30
31 struct pci_device_id pci_device_id_DevicePCI[] =
32 {
33 {VENDOR_ID, DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
34 {} // end of list
35 };
36
37 struct pci_driver pci_driver_DevicePCI =
38 {
39 name: "MyPCIDevice",
40 id_table: pci_device_id_DevicePCI,
41 probe: device_probe,
42 remove: device_remove
43 };
44
45
46 int init_module(void)
47 {
48 struct pci_dev *pdev = NULL;
49 int ret = 0;
50
51 pci_register_driver(&pci_driver_DevicePCI);
52 pdev = pci_get_device(VENDOR_ID, DEVICE_ID, NULL);
53 if (pdev)
54 {
55 LOG("Device found ... ");
56 pci_dev = pdev;
57 }
58 else
59 {
60 LOG("Device not found ... ");
61 }
62 return ret;
63
64
65 }
66
67 void cleanup_module(void)
68 {
69 pci_unregister_driver(&pci_driver_DevicePCI);
70
71 }
72
73 int device_probe(struct pci_dev *dev, const struct pci_device_id *id)
74 {
75 int ret;
76 LOG("Devie probed");
77 ret = pci_enable_device(dev);
78 if (ret < 0 ) LOG("Failed while enabling ... ");
79
80 return ret;
81 }
82
83 void device_remove(struct pci_dev *dev)
84 {
85 pci_release_regions(dev);
86 pci_disable_device(dev);
87 }
Inside init_module() function, given user VID and DID device is found and if successful, struct pdev is pointing to the respective pci device. As i have read, probe() function kicks in as soon as the device is found.
Does this mean we always have to do pci_get_device() before calling the pci_enable_device()?
IMO, yes but if so, how do device_probe() get reference to dev structure even though i am not passing it?
If i am 100% sure that my device exists on the system, how can i call pci_enable_device() without registering?
I am currently referring LDD3 book where they explain all the calls but for a beginner i feel it misses out how to connect the dot. Does any one have pointers where widely used pci_xx() calls are explained with neat examples?
Your probe function is called by pci_register_driver, which searches for an unclaimed device with a matching device ID.
Your pci_get_device call happens after probe has returned, and is not needed.
My question is how fast is mprotect. What will be the difference between mprotecting say 1 MB of contiguous memory as compared to 1 GB of contiguous memory? Of course I can measure the time, but I want to know what goes under the hood.
A quick check on the source seems to indicate that it iterates over the process mappings in the selected region and change their flags. If you protect less than a whole mapping it'll split it into two or three.
So in short it's O(n) where n is the number of times you've called mmap.
You can see all the current maps in /proc/pid/maps
It is O(n) on page count in the region too, because it should change a access bits on all PTEs (Page translation Entries, which describes virtual->physical page mappings in PageTable). Calltree:
mprotect
->
mprotect_fixup
->
change_pte_range
http://lxr.free-electrons.com/source/mm/mprotect.c#L32
47 do {
48 oldpte = *pte;
49 if (pte_present(oldpte)) {
50 pte_t ptent;
51
52 ptent = ptep_modify_prot_start(mm, addr, pte);
53 ptent = pte_modify(ptent, newprot);
54
55 /*
56 * Avoid taking write faults for pages we know to be
57 * dirty.
58 */
59 if (dirty_accountable && pte_dirty(ptent))
60 ptent = pte_mkwrite(ptent);
61
62 ptep_modify_prot_commit(mm, addr, pte, ptent);
63 } else if (PAGE_MIGRATION && !pte_file(oldpte)) {
64 swp_entry_t entry = pte_to_swp_entry(oldpte);
65
66 if (is_write_migration_entry(entry)) {
67 /*
68 * A protection check is difficult so
69 * just be safe and disable write
70 */
71 make_migration_entry_read(&entry);
72 set_pte_at(mm, addr, pte,
73 swp_entry_to_pte(entry));
74 }
75 }
76 } while (pte++, addr += PAGE_SIZE, addr != end);
Note the increment: addr += PAGE_SIZE, addr != end);