@@ -101,6 +101,18 @@ static void rt_vdso_counter_to_timespec(rt_uint64_t counter_value,
101101 ts -> tv_nsec = monotonic_ns % RT_VDSO_NSEC_PER_SEC ;
102102}
103103
104+ static struct timespec rt_vdso_timespec_subtract (const struct timespec * lhs ,
105+ const struct timespec * rhs )
106+ {
107+ struct timespec ret ;
108+
109+ ret .tv_sec = lhs -> tv_sec - rhs -> tv_sec ;
110+ ret .tv_nsec = lhs -> tv_nsec - rhs -> tv_nsec ;
111+ rt_vdso_normalize_timespec (& ret );
112+
113+ return ret ;
114+ }
115+
104116static struct timespec rt_vdso_add_timespec (const struct timespec * lhs ,
105117 const struct timespec * rhs )
106118{
@@ -129,15 +141,58 @@ static int rt_vdso_read_monotonic_snapshot(struct timespec *monotonic_time,
129141 return RT_EOK ;
130142}
131143
144+ static void rt_vdso_update_data_page_flags (void )
145+ {
146+ rt_uint32_t flags = 0 ;
147+
148+ if (rt_vdso_realtime_offset_ready )
149+ {
150+ flags |= RT_VDSO_FLAG_REALTIME_VALID ;
151+ }
152+
153+ rt_vdso_kernel_data_page -> flags = flags ;
154+ }
155+
132156static void rt_vdso_store_clock_snapshot (const struct timespec * monotonic_time ,
133157 rt_uint64_t counter_value ,
134158 rt_uint64_t counter_freq )
135159{
136160 rt_vdso_kernel_data_page -> counter_last = counter_value ;
137161 rt_vdso_kernel_data_page -> counter_freq = counter_freq ;
162+ rt_vdso_update_data_page_flags ();
138163 rt_vdso_kernel_data_page -> base_time [RT_VDSO_CLOCK_MONOTONIC_INDEX ] = * monotonic_time ;
139- rt_vdso_kernel_data_page -> base_time [RT_VDSO_CLOCK_REALTIME_INDEX ] =
140- rt_vdso_add_timespec (monotonic_time , & rt_vdso_realtime_offset );
164+ if (rt_vdso_realtime_offset_ready )
165+ {
166+ rt_vdso_kernel_data_page -> base_time [RT_VDSO_CLOCK_REALTIME_INDEX ] =
167+ rt_vdso_add_timespec (monotonic_time , & rt_vdso_realtime_offset );
168+ }
169+ else
170+ {
171+ rt_vdso_kernel_data_page -> base_time [RT_VDSO_CLOCK_REALTIME_INDEX ] = * monotonic_time ;
172+ }
173+ }
174+
175+ void rt_vdso_set_realtime (const struct timespec * realtime )
176+ {
177+ struct timespec monotonic ;
178+ rt_uint64_t counter ;
179+ rt_uint64_t freq ;
180+
181+ if (rt_vdso_runtime_status != RT_EOK || realtime == RT_NULL )
182+ {
183+ return ;
184+ }
185+
186+ if (rt_vdso_read_monotonic_snapshot (& monotonic , & counter , & freq ) != RT_EOK )
187+ {
188+ return ;
189+ }
190+
191+ rt_vdso_data_page_write_begin (rt_vdso_kernel_data_page );
192+ rt_vdso_realtime_offset = rt_vdso_timespec_subtract (realtime , & monotonic );
193+ rt_vdso_realtime_offset_ready = RT_TRUE ;
194+ rt_vdso_store_clock_snapshot (& monotonic , counter , freq );
195+ rt_vdso_data_page_write_end (rt_vdso_kernel_data_page );
141196}
142197
143198static void * rt_vdso_map_physical_pages (struct rt_lwp * lwp , void * user_va ,
@@ -209,7 +264,7 @@ static int rt_vdso_map_binary_pages(enum rt_vdso_binary_id binary_id,
209264 if (data_page_base == RT_NULL )
210265 {
211266 lwp -> vdso_vbase = RT_NULL ;
212- return RT_ERROR ;
267+ return - RT_ERROR ;
213268 }
214269
215270 image_base = (uint8_t * )data_page_base + data_page_len ;
@@ -221,7 +276,7 @@ static int rt_vdso_map_binary_pages(enum rt_vdso_binary_id binary_id,
221276 {
222277 lwp_unmap_user_phy (lwp , data_page_base );
223278 lwp -> vdso_vbase = RT_NULL ;
224- return RT_ERROR ;
279+ return - RT_ERROR ;
225280 }
226281
227282 lwp -> vdso_vbase = image_base ;
@@ -266,6 +321,7 @@ static int rt_vdso_validate_image(void)
266321
267322 rt_memset (rt_vdso_data_page_store .raw , 0 , sizeof (rt_vdso_data_page_store .raw ));
268323 rt_vdso_realtime_offset_ready = RT_FALSE ;
324+ rt_memset (& rt_vdso_realtime_offset , 0 , sizeof (rt_vdso_realtime_offset ));
269325
270326 if (rt_memcmp (rt_vdso_binaries [RT_VDSO_BINARY_COMMON ].image_start ,
271327 RT_VDSO_IMAGE_ELF_MAGIC , RT_VDSO_IMAGE_ELF_MAGIC_LEN ))
0 commit comments