The commit is pushed to "branch-rh7-3.10.0-123.1.2-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git after rh7-3.10.0-123.1.2.vz7.4.10 ------> commit d2b8e29be14cbd4da0b641156fffd9204ca0d70a Author: Vladimir Davydov <vdavy...@parallels.com> Date: Thu May 7 20:28:18 2015 +0400
ve/printk/ppc: fix asm modifier in DEFINE_STRUCT_MEMBER_ALIAS This was found while tring to compile the kernel with a stock config (i.e. no CONFIG_BEANCOUNTERS, CONFIG_VE etc.) and boot it on IBM Power8. ============================================================= gcc fails to parse %a0 on PPC for some reason. Use conventional %c0 instead. > â%cdigitâ can be used to substitute an operand that is a constant > value without the syntax that normally indicates an immediate operand. [...] > â%adigitâ can be used to substitute an operand as if it were a memory > reference, with the actual operand treated as the address. This may be > useful when outputting a âload addressâ instruction, because often the > assembler syntax for such an instruction requires you to write the > operand as if it were a memory reference. (Source: https://gcc.gnu.org/onlinedocs/gccint/Output-Template.html#Output-Template) Also from GCC source code (gcc/final.c): > /* Output text from TEMPLATE to the assembler output file, > obeying %-directions to substitute operands taken from > the vector OPERANDS. > > %N (for N a digit) means print operand N in usual manner. > %lN means require operand N to be a CODE_LABEL or LABEL_REF > and print the label name with no punctuation. > %cN means require operand N to be a constant > and print the constant expression with no punctuation. > %aN means expect operand N to be a memory address > (not a memory reference!) and print a reference > to that address. > %nN means expect operand N to be a constant > and print a constant expression for minus the value > of the operand, with no other punctuation. */ I want to define log_buf, log_buf_len, etc as aliases for init_log_state.buf, init_log_state.buf_len, etc. So for log_buf_len (offset 0x8 in struct log_state on 64 bit) I want to generate .globl log_buf_len .set log_buf_len, init_log_state+0x8 ^^^ NOTE: No punctuation here (no $ sign, which is prepended if "%N" is used) So I obviously should have used "%cN", because it explicitly states: "constant expression with no punctuation". It turns out that "%aN" also fits on Linux/x86, because it seems that a memory address can always be used as a memory offset. However, it seems that on Linux/PPC gcc expects a memory address to be in some specific range, otherwise it just crashes, so that offset and address are orthogonal things. Hope this explains the magic behind this patch. Signed-off-by: Vladimir Davydov <vdavy...@parallels.com> --- kernel/printk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/printk.c b/kernel/printk.c index 9ee2b80..51805a54 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -293,7 +293,7 @@ static struct log_state { static void ____ ## name ## _definition(void) __attribute__((used)); \ static void ____ ## name ## _definition(void) \ { \ - asm (".globl " #name "\n\t.set " #name ", " #inst "+%a0" \ + asm (".globl " #name "\n\t.set " #name ", " #inst "+%c0" \ : : "g" (offsetof(typeof(inst), memb))); \ } \ extern typeof(inst.memb) name;
_______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel